basalt-ui 1.11.0 → 1.12.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.
- package/AGENTS.md +21 -21
- package/CHANGELOG.md +15 -0
- package/README.md +36 -27
- package/agent/rules/basalt-content.md +16 -3
- package/dist/agent/adapter.d.ts +146 -0
- package/dist/agent/adapter.d.ts.map +1 -0
- package/dist/agent/adapter.js +473 -0
- package/dist/agent/adapter.test.d.ts +2 -0
- package/dist/agent/adapter.test.d.ts.map +1 -0
- package/dist/agent/ai-sdk-transport.test.d.ts +2 -0
- package/dist/agent/ai-sdk-transport.test.d.ts.map +1 -0
- package/dist/agent/coalesce.d.ts +20 -4
- package/dist/agent/coalesce.d.ts.map +1 -1
- package/dist/agent/coalesce.js +76 -8
- package/dist/agent/coalesce.test.d.ts +2 -0
- package/dist/agent/coalesce.test.d.ts.map +1 -0
- package/dist/agent/foreign.test.d.ts +2 -0
- package/dist/agent/foreign.test.d.ts.map +1 -0
- package/dist/agent/id.d.ts +30 -0
- package/dist/agent/id.d.ts.map +1 -1
- package/dist/agent/id.js +16 -0
- package/dist/agent/id.test.d.ts +2 -0
- package/dist/agent/id.test.d.ts.map +1 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +3 -0
- package/dist/agent/merge.d.ts.map +1 -1
- package/dist/agent/merge.js +19 -7
- package/dist/agent/merge.test.d.ts +2 -0
- package/dist/agent/merge.test.d.ts.map +1 -0
- package/dist/agent/part-list.d.ts +49 -34
- package/dist/agent/part-list.d.ts.map +1 -1
- package/dist/agent/part-list.js +42 -6
- package/dist/agent/part-list.test.d.ts +2 -0
- package/dist/agent/part-list.test.d.ts.map +1 -0
- package/dist/agent/parts.d.ts +46 -10
- package/dist/agent/parts.d.ts.map +1 -1
- package/dist/agent/parts.js +16 -6
- package/dist/agent/parts.test.d.ts +2 -0
- package/dist/agent/parts.test.d.ts.map +1 -0
- package/dist/agent/thread.d.ts +14 -0
- package/dist/agent/thread.d.ts.map +1 -1
- package/dist/agent/thread.js +8 -2
- package/dist/agent/thread.test.d.ts +2 -0
- package/dist/agent/thread.test.d.ts.map +1 -0
- package/dist/agent/transport.test.d.ts +2 -0
- package/dist/agent/transport.test.d.ts.map +1 -0
- package/dist/agent/use-agent-stream.test.d.ts +2 -0
- package/dist/agent/use-agent-stream.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +1 -0
- package/dist/agent-chat/composer.d.ts +130 -8
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +189 -23
- package/dist/agent-chat/composer.test.d.ts +2 -0
- package/dist/agent-chat/composer.test.d.ts.map +1 -0
- package/dist/agent-chat/index.d.ts +1 -1
- package/dist/agent-chat/index.d.ts.map +1 -1
- package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
- package/dist/agent-chat/thread-detail-panel.js +1 -1
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +14 -3
- package/dist/agent-chat/thread-message.test.d.ts +2 -0
- package/dist/agent-chat/thread-message.test.d.ts.map +1 -0
- package/dist/agent-chat/thread-workspace.js +1 -1
- package/dist/agent-chat/tool-chip.test.d.ts +2 -0
- package/dist/agent-chat/tool-chip.test.d.ts.map +1 -0
- package/dist/charts/primitives/ChartFrame.test.d.ts +2 -0
- package/dist/charts/primitives/ChartFrame.test.d.ts.map +1 -0
- package/dist/charts/utils/domain.test.d.ts +2 -0
- package/dist/charts/utils/domain.test.d.ts.map +1 -0
- package/dist/cli/check-theme.test.d.ts +2 -0
- package/dist/cli/check-theme.test.d.ts.map +1 -0
- package/dist/cli/help.test.d.ts +2 -0
- package/dist/cli/help.test.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/init-sync.test.d.ts +2 -0
- package/dist/cli/init-sync.test.d.ts.map +1 -0
- package/dist/cli/placement-engine.test.d.ts +2 -0
- package/dist/cli/placement-engine.test.d.ts.map +1 -0
- package/dist/cli/tarball-parity.test.d.ts +2 -0
- package/dist/cli/tarball-parity.test.d.ts.map +1 -0
- package/dist/cli/template-format.test.d.ts +2 -0
- package/dist/cli/template-format.test.d.ts.map +1 -0
- package/dist/cli/template-ledger.test.d.ts +2 -0
- package/dist/cli/template-ledger.test.d.ts.map +1 -0
- package/dist/cli/tokens-css.test.d.ts +2 -0
- package/dist/cli/tokens-css.test.d.ts.map +1 -0
- package/dist/content/article-actions.test.d.ts +2 -0
- package/dist/content/article-actions.test.d.ts.map +1 -0
- package/dist/content/article-model.test.d.ts +2 -0
- package/dist/content/article-model.test.d.ts.map +1 -0
- package/dist/content/block-split.test.d.ts +2 -0
- package/dist/content/block-split.test.d.ts.map +1 -0
- package/dist/content/fence-block.d.ts +37 -10
- package/dist/content/fence-block.d.ts.map +1 -1
- package/dist/content/fence-block.js +80 -14
- package/dist/content/heading-components.d.ts.map +1 -1
- package/dist/content/heading-components.js +7 -4
- package/dist/content/heading-components.test.d.ts +2 -0
- package/dist/content/heading-components.test.d.ts.map +1 -0
- package/dist/content/index.d.ts +6 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +5 -1
- package/dist/content/markdown.d.ts +101 -14
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +141 -28
- package/dist/content/markdown.test.d.ts +2 -0
- package/dist/content/markdown.test.d.ts.map +1 -0
- package/dist/content/prose.module.css.test.d.ts +2 -0
- package/dist/content/prose.module.css.test.d.ts.map +1 -0
- package/dist/content/sanitize.d.ts +170 -0
- package/dist/content/sanitize.d.ts.map +1 -0
- package/dist/content/sanitize.js +178 -0
- package/dist/content/sanitize.test.d.ts +2 -0
- package/dist/content/sanitize.test.d.ts.map +1 -0
- package/dist/content/slug.test.d.ts +2 -0
- package/dist/content/slug.test.d.ts.map +1 -0
- package/dist/dashboard/stat-card.test.d.ts +2 -0
- package/dist/dashboard/stat-card.test.d.ts.map +1 -0
- package/dist/guard/check-source.test.d.ts +2 -0
- package/dist/guard/check-source.test.d.ts.map +1 -0
- package/dist/guard/guard-hook.test.d.ts +2 -0
- package/dist/guard/guard-hook.test.d.ts.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/provider/index.test.d.ts +2 -0
- package/dist/provider/index.test.d.ts.map +1 -0
- package/dist/provider/lab-theme.test.d.ts +2 -0
- package/dist/provider/lab-theme.test.d.ts.map +1 -0
- package/dist/router-tanstack/multi-search-param-store.test.d.ts +2 -0
- package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +1 -0
- package/dist/styles.floor.test.d.ts +2 -0
- package/dist/styles.floor.test.d.ts.map +1 -0
- package/dist/surfaces.d.ts +4 -4
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +12 -3
- package/dist/theme/border-coverage.test.d.ts +18 -0
- package/dist/theme/border-coverage.test.d.ts.map +1 -0
- package/dist/theme/contrast.test.d.ts +2 -0
- package/dist/theme/contrast.test.d.ts.map +1 -0
- package/dist/theme/density-option.test.d.ts +2 -0
- package/dist/theme/density-option.test.d.ts.map +1 -0
- package/dist/theme/density-relations.test.d.ts +2 -0
- package/dist/theme/density-relations.test.d.ts.map +1 -0
- package/dist/theme/derive-theme.test.d.ts +2 -0
- package/dist/theme/derive-theme.test.d.ts.map +1 -0
- package/dist/theme/fonts-option.test.d.ts +2 -0
- package/dist/theme/fonts-option.test.d.ts.map +1 -0
- package/dist/theme/radius-option.test.d.ts +2 -0
- package/dist/theme/radius-option.test.d.ts.map +1 -0
- package/dist/theme/radius.test.d.ts +2 -0
- package/dist/theme/radius.test.d.ts.map +1 -0
- package/dist/theme/shadow-surfaces.test.d.ts +26 -0
- package/dist/theme/shadow-surfaces.test.d.ts.map +1 -0
- package/dist/theme/spacing.test.d.ts +2 -0
- package/dist/theme/spacing.test.d.ts.map +1 -0
- package/dist/theme/use-basalt-spacing.test.d.ts +2 -0
- package/dist/theme/use-basalt-spacing.test.d.ts.map +1 -0
- package/dist/theme-lab/derive-controls.test.d.ts +2 -0
- package/dist/theme-lab/derive-controls.test.d.ts.map +1 -0
- package/dist/theme-lab/derive-state.test.d.ts +2 -0
- package/dist/theme-lab/derive-state.test.d.ts.map +1 -0
- package/dist/theme-lab/theme-lab.test.d.ts +2 -0
- package/dist/theme-lab/theme-lab.test.d.ts.map +1 -0
- package/dist/tokens/build-fonts-css.test.d.ts +2 -0
- package/dist/tokens/build-fonts-css.test.d.ts.map +1 -0
- package/dist/tokens/build-radius-css.test.d.ts +2 -0
- package/dist/tokens/build-radius-css.test.d.ts.map +1 -0
- package/dist/tokens/density.test.d.ts +2 -0
- package/dist/tokens/density.test.d.ts.map +1 -0
- package/dist/tokens/derive-radius.test.d.ts +2 -0
- package/dist/tokens/derive-radius.test.d.ts.map +1 -0
- package/dist/tokens/derive.test.d.ts +2 -0
- package/dist/tokens/derive.test.d.ts.map +1 -0
- package/dist/tokens/palette.test.d.ts +2 -0
- package/dist/tokens/palette.test.d.ts.map +1 -0
- package/dist/vite-color-mix.test.d.ts +2 -0
- package/dist/vite-color-mix.test.d.ts.map +1 -0
- package/dist/vite.test.d.ts +2 -0
- package/dist/vite.test.d.ts.map +1 -0
- package/llms.txt +6 -6
- package/package.json +6 -1
- package/src/agent/adapter.test.ts +1403 -0
- package/src/agent/adapter.ts +887 -0
- package/src/agent/ai-sdk-transport.test.ts +53 -26
- package/src/agent/coalesce.test.ts +202 -9
- package/src/agent/coalesce.ts +126 -15
- package/src/agent/foreign.test.ts +5 -1
- package/src/agent/id.test.ts +6 -2
- package/src/agent/id.ts +48 -0
- package/src/agent/index.ts +8 -0
- package/src/agent/merge.test.ts +87 -0
- package/src/agent/merge.ts +57 -10
- package/src/agent/part-list.test.tsx +31 -1
- package/src/agent/part-list.tsx +77 -29
- package/src/agent/parts.test.ts +121 -4
- package/src/agent/parts.ts +78 -17
- package/src/agent/thread.test.ts +75 -2
- package/src/agent/thread.ts +21 -1
- package/src/agent/use-agent-stream.test.tsx +9 -5
- package/src/agent/use-agent-thread-runs.foreign.test.tsx +5 -0
- package/src/agent/use-agent-thread-runs.resume.test.tsx +16 -11
- package/src/agent/use-agent-thread-runs.test.tsx +30 -17
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +13 -7
- package/src/agent-chat/composer.test.tsx +924 -0
- package/src/agent-chat/composer.tsx +521 -52
- package/src/agent-chat/index.ts +1 -1
- package/src/agent-chat/thread-detail-panel.tsx +3 -1
- package/src/agent-chat/thread-message.test.tsx +141 -1
- package/src/agent-chat/thread-message.tsx +29 -4
- package/src/agent-chat/thread-workspace.tsx +1 -1
- package/src/cli/index.ts +0 -1
- package/src/cli/template-format.test.ts +2 -2
- package/src/content/fence-block.tsx +242 -15
- package/src/content/heading-components.test.tsx +65 -0
- package/src/content/heading-components.tsx +26 -5
- package/src/content/index.ts +19 -3
- package/src/content/markdown.test.tsx +603 -0
- package/src/content/markdown.tsx +355 -35
- package/src/content/sanitize.test.ts +659 -0
- package/src/content/sanitize.ts +510 -0
- package/src/dashboard/stat-card.test.tsx +6 -1
- package/src/index.ts +13 -1
- package/src/surfaces.ts +12 -3
- package/src/theme/contrast.test.ts +1 -4
- package/src/theme/density-relations.test.ts +4 -2
- package/src/theme/fonts-option.test.ts +7 -1
- package/src/theme/shadow-surfaces.test.ts +12 -6
- package/src/theme/use-basalt-spacing.test.tsx +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball-parity.test.d.ts","sourceRoot":"","sources":["../../src/cli/tarball-parity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-format.test.d.ts","sourceRoot":"","sources":["../../src/cli/template-format.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-ledger.test.d.ts","sourceRoot":"","sources":["../../src/cli/template-ledger.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens-css.test.d.ts","sourceRoot":"","sources":["../../src/cli/tokens-css.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-actions.test.d.ts","sourceRoot":"","sources":["../../src/content/article-actions.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-model.test.d.ts","sourceRoot":"","sources":["../../src/content/article-model.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-split.test.d.ts","sourceRoot":"","sources":["../../src/content/block-split.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,19 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Element } from 'hast';
|
|
3
|
+
export type FenceRenderContext = {
|
|
4
|
+
/** The fence body, without the surrounding fence markers. */
|
|
5
|
+
readonly code: string;
|
|
6
|
+
/** The info string's first word (` ```ts title="x" ` → `'ts'`), absent on a bare fence. */
|
|
7
|
+
readonly language?: string;
|
|
8
|
+
/** Raw meta string after the language on the opening fence line (`'title="x"'` above). */
|
|
9
|
+
readonly meta?: string;
|
|
10
|
+
/** Parsed `title="…"` out of `meta` — the filename tab `CodeBlock` renders. */
|
|
11
|
+
readonly title?: string;
|
|
12
|
+
/** `false` only for the in-flight tail block of a streaming message. Monotone: never true→false. */
|
|
13
|
+
readonly settled: boolean;
|
|
14
|
+
};
|
|
1
15
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
16
|
+
* `undefined` DECLINES — the fence falls back to the default `CodeBlock` rendering, no different
|
|
17
|
+
* from an unclaimed language. `null` is NOT a decline; it is a deliberate "render nothing" result
|
|
18
|
+
* and is used as-is. A renderer that THROWS is also contained and falls back to `CodeBlock` (see the
|
|
19
|
+
* module doc above) — no renderer needs its own try/parse/fallback scaffolding to survive malformed,
|
|
20
|
+
* model-authored fence bodies.
|
|
21
|
+
*/
|
|
22
|
+
export type FenceRenderer = (ctx: FenceRenderContext) => ReactNode;
|
|
23
|
+
/** Fence renderers keyed by language. */
|
|
24
|
+
export type FenceRenderers = Readonly<Record<string, FenceRenderer>>;
|
|
25
|
+
/**
|
|
26
|
+
* Wraps a renderer that is only worth running on finished text: renders the plain `CodeBlock`
|
|
27
|
+
* while the fence is still streaming, then `render` once its block settles. The built-in `mermaid`
|
|
28
|
+
* entry IS this — a consumer's own heavyweight fence (a chart spec, a diagram DSL) wants the same
|
|
29
|
+
* deal.
|
|
5
30
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* wasted parse pass on a still-changing diagram. Every other fenced language hides its copy
|
|
9
|
-
* action while unsettled for the same reason (copying a still-streaming block is misleading).
|
|
31
|
+
* @example
|
|
32
|
+
* import { settledOnly } from 'basalt-ui/content'
|
|
10
33
|
*
|
|
11
|
-
*
|
|
34
|
+
* <Markdown fenceRenderers={{ vega: settledOnly(({ code }) => <VegaChart spec={code} />) }}>
|
|
12
35
|
*/
|
|
13
|
-
|
|
36
|
+
export declare function settledOnly(render: FenceRenderer): FenceRenderer;
|
|
37
|
+
/** basalt's own fence renderers. A consumer entry for the same key wins over these. */
|
|
38
|
+
export declare const BUILT_IN_FENCE_RENDERERS: FenceRenderers;
|
|
14
39
|
export type FenceBlockProps = {
|
|
15
40
|
readonly node?: Element;
|
|
16
41
|
readonly settled: boolean;
|
|
42
|
+
/** Consumer overrides, consulted BEFORE `BUILT_IN_FENCE_RENDERERS`. */
|
|
43
|
+
readonly renderers?: FenceRenderers;
|
|
17
44
|
};
|
|
18
|
-
export declare function FenceBlock({ node, settled }: FenceBlockProps): import("react").JSX.Element | null;
|
|
45
|
+
export declare function FenceBlock({ node, settled, renderers }: FenceBlockProps): import("react").JSX.Element | null;
|
|
19
46
|
//# sourceMappingURL=fence-block.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fence-block.d.ts","sourceRoot":"","sources":["../../src/content/fence-block.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fence-block.d.ts","sourceRoot":"","sources":["../../src/content/fence-block.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAOnC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,oGAAoG;IACpG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,kBAAkB,KAAK,SAAS,CAAA;AAElE,yCAAyC;AACzC,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;AAYpE;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAEhE;AAED,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,EAAE,cAEtC,CAAA;AAiBD,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAA;CACpC,CAAA;AA2HD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,eAAe,sCA2BvE"}
|
|
@@ -1,23 +1,89 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Component, useRef } from "react";
|
|
2
3
|
import { CodeBlock } from "./code-block.js";
|
|
3
4
|
import { extractFenceInfo } from "./markdown-hast.js";
|
|
4
5
|
import { MermaidDiagram } from "./mermaid.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const defaultFenceRenderer = ({ code, language, title, settled }) => /* @__PURE__ */ jsx(
|
|
7
|
+
CodeBlock,
|
|
8
|
+
{
|
|
9
|
+
code,
|
|
10
|
+
showCopy: settled,
|
|
11
|
+
...language !== void 0 && { language },
|
|
12
|
+
...title !== void 0 && { title }
|
|
10
13
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
);
|
|
15
|
+
function settledOnly(render) {
|
|
16
|
+
return (ctx) => ctx.settled ? render(ctx) : defaultFenceRenderer(ctx);
|
|
17
|
+
}
|
|
18
|
+
const BUILT_IN_FENCE_RENDERERS = {
|
|
19
|
+
mermaid: settledOnly(({ code }) => /* @__PURE__ */ jsx(MermaidDiagram, { code }))
|
|
20
|
+
};
|
|
21
|
+
function extractFenceMeta(preNode) {
|
|
22
|
+
const codeNode = preNode.children.find(
|
|
23
|
+
(child) => child.type === "element" && child.tagName === "code"
|
|
19
24
|
);
|
|
25
|
+
const data = codeNode?.data;
|
|
26
|
+
return data?.meta;
|
|
27
|
+
}
|
|
28
|
+
function lookupFenceRenderer(registry, language) {
|
|
29
|
+
if (registry === void 0 || !Object.hasOwn(registry, language)) return void 0;
|
|
30
|
+
const candidate = registry[language];
|
|
31
|
+
return typeof candidate === "function" ? candidate : void 0;
|
|
32
|
+
}
|
|
33
|
+
function warnFenceRendererThrew(warned, error) {
|
|
34
|
+
if (warned.current) return;
|
|
35
|
+
warned.current = true;
|
|
36
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
37
|
+
console.warn(
|
|
38
|
+
"[basalt] FenceBlock: a fence renderer threw \u2014 falling back to the default CodeBlock rendering.",
|
|
39
|
+
error
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function renderFenceSafely(render, ctx, warned) {
|
|
44
|
+
let rendered;
|
|
45
|
+
try {
|
|
46
|
+
rendered = render(ctx);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
warnFenceRendererThrew(warned, error);
|
|
49
|
+
return defaultFenceRenderer(ctx);
|
|
50
|
+
}
|
|
51
|
+
return rendered === void 0 ? defaultFenceRenderer(ctx) : rendered;
|
|
52
|
+
}
|
|
53
|
+
class FenceRenderBoundary extends Component {
|
|
54
|
+
constructor(props) {
|
|
55
|
+
super(props);
|
|
56
|
+
this.state = { hasError: false };
|
|
57
|
+
}
|
|
58
|
+
static getDerivedStateFromError() {
|
|
59
|
+
return { hasError: true };
|
|
60
|
+
}
|
|
61
|
+
componentDidCatch(error) {
|
|
62
|
+
warnFenceRendererThrew(this.props.warned, error);
|
|
63
|
+
}
|
|
64
|
+
render() {
|
|
65
|
+
return this.state.hasError ? defaultFenceRenderer(this.props.ctx) : this.props.children;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function FenceBlock({ node, settled, renderers }) {
|
|
69
|
+
const warned = useRef(false);
|
|
70
|
+
const fence = node ? extractFenceInfo(node) : void 0;
|
|
71
|
+
if (!fence) return null;
|
|
72
|
+
const meta = node ? extractFenceMeta(node) : void 0;
|
|
73
|
+
const ctx = {
|
|
74
|
+
code: fence.code,
|
|
75
|
+
settled,
|
|
76
|
+
...fence.language !== void 0 && { language: fence.language },
|
|
77
|
+
...fence.title !== void 0 && { title: fence.title },
|
|
78
|
+
...meta !== void 0 && { meta }
|
|
79
|
+
};
|
|
80
|
+
const language = fence.language;
|
|
81
|
+
const render = language === void 0 ? void 0 : lookupFenceRenderer(renderers, language) ?? lookupFenceRenderer(BUILT_IN_FENCE_RENDERERS, language);
|
|
82
|
+
const active = render ?? defaultFenceRenderer;
|
|
83
|
+
return /* @__PURE__ */ jsx(FenceRenderBoundary, { ctx, warned, children: renderFenceSafely(active, ctx, warned) }, ctx.code);
|
|
20
84
|
}
|
|
21
85
|
export {
|
|
22
|
-
|
|
86
|
+
BUILT_IN_FENCE_RENDERERS,
|
|
87
|
+
FenceBlock,
|
|
88
|
+
settledOnly
|
|
23
89
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading-components.d.ts","sourceRoot":"","sources":["../../src/content/heading-components.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"heading-components.d.ts","sourceRoot":"","sources":["../../src/content/heading-components.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,gBAAgB,CAAA;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AA8CzC,yFAAyF;AACzF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CASjF"}
|
|
@@ -18,11 +18,14 @@ function headingText(node) {
|
|
|
18
18
|
}
|
|
19
19
|
function createHeadingRenderer(level, tracker) {
|
|
20
20
|
const Tag = HEADING_TAGS[level];
|
|
21
|
-
return function HeadingRenderer({ children }) {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
return function HeadingRenderer({ id, children, node: _node, ...rest }) {
|
|
22
|
+
if (id !== void 0) {
|
|
23
|
+
return /* @__PURE__ */ jsx(Tag, { id, ...rest, children });
|
|
24
|
+
}
|
|
25
|
+
const slug = tracker.slug(headingText(children));
|
|
26
|
+
return /* @__PURE__ */ jsxs(Tag, { id: slug, ...rest, children: [
|
|
24
27
|
children,
|
|
25
|
-
/* @__PURE__ */ jsx(HeadingAnchor, { id })
|
|
28
|
+
/* @__PURE__ */ jsx(HeadingAnchor, { id: slug })
|
|
26
29
|
] });
|
|
27
30
|
};
|
|
28
31
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-components.test.d.ts","sourceRoot":"","sources":["../../src/content/heading-components.test.tsx"],"names":[],"mappings":""}
|
package/dist/content/index.d.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Mantine-coupled (like `./forms`/`./notifications`/`./data`): prose typography, a shiki-backed
|
|
5
5
|
* code block (optional peer, lazy singleton), a semantic callout, a scroll-spy TOC rail, a
|
|
6
6
|
* scroll-driven reading-progress bar, a streaming-aware `Markdown` renderer (react-markdown +
|
|
7
|
-
* remark-gfm, optional peers)
|
|
7
|
+
* remark-gfm + rehype-sanitize + remend, all optional peers) with its fence-renderer registry,
|
|
8
|
+
* `MermaidDiagram` (beautiful-mermaid, optional peer), the MDX
|
|
8
9
|
* component map, the docs-page frame (`ArticleLayout`), overview cards (`ArticleCard`/
|
|
9
10
|
* `ArticleGrid`), and the contextual-help drawer (`GuideLink`/`GuideDrawer`). See
|
|
10
11
|
* `agent/rules/basalt-content.md` for the full doctrine + the content-collections recipe.
|
|
@@ -23,8 +24,10 @@ export { headingSlug, readingTime, SlugTracker } from './slug.js';
|
|
|
23
24
|
export type { ReadingTime } from './slug.js';
|
|
24
25
|
export { HeadingAnchor } from './heading-anchor.js';
|
|
25
26
|
export type { HeadingAnchorProps } from './heading-anchor.js';
|
|
26
|
-
export { Markdown } from './markdown.js';
|
|
27
|
-
export type { MarkdownComponents, MarkdownProps } from './markdown.js';
|
|
27
|
+
export { Markdown, settledOnly } from './markdown.js';
|
|
28
|
+
export type { FenceRenderContext, FenceRenderer, FenceRenderers, MarkdownComponents, MarkdownContentTrust, MarkdownProps, } from './markdown.js';
|
|
29
|
+
export { BASALT_SANITIZE_SCHEMA, mergeSanitizeSchema } from './sanitize.js';
|
|
30
|
+
export type { SanitizePropertyDefinition, SanitizeSchema, SanitizeSchemaExtension, SanitizeSchemaInput, } from './sanitize.js';
|
|
28
31
|
export { MermaidDiagram } from './mermaid.js';
|
|
29
32
|
export type { MermaidDiagramProps } from './mermaid.js';
|
|
30
33
|
export { blockSplit } from './block-split.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AACvC,YAAY,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAE9D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC9D,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAE1D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAClD,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACxE,YAAY,EACV,0BAA0B,EAC1B,cAAc,EACd,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,YAAY,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1D,YAAY,EAAE,0BAA0B,EAAE,MAAM,OAAO,CAAA;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE/F,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACzD,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjF,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA"}
|
package/dist/content/index.js
CHANGED
|
@@ -5,7 +5,8 @@ import { TableOfContents } from "./toc.js";
|
|
|
5
5
|
import { ReadingProgress } from "./reading-progress.js";
|
|
6
6
|
import { headingSlug, readingTime, SlugTracker } from "./slug.js";
|
|
7
7
|
import { HeadingAnchor } from "./heading-anchor.js";
|
|
8
|
-
import { Markdown } from "./markdown.js";
|
|
8
|
+
import { Markdown, settledOnly } from "./markdown.js";
|
|
9
|
+
import { BASALT_SANITIZE_SCHEMA, mergeSanitizeSchema } from "./sanitize.js";
|
|
9
10
|
import { MermaidDiagram } from "./mermaid.js";
|
|
10
11
|
import { blockSplit } from "./block-split.js";
|
|
11
12
|
import { createMdxComponents, mdxComponents } from "./mdx.js";
|
|
@@ -20,6 +21,7 @@ export {
|
|
|
20
21
|
ArticleFilterBar,
|
|
21
22
|
ArticleGrid,
|
|
22
23
|
ArticleLayout,
|
|
24
|
+
BASALT_SANITIZE_SCHEMA,
|
|
23
25
|
Callout,
|
|
24
26
|
CodeBlock,
|
|
25
27
|
GuideDrawer,
|
|
@@ -37,7 +39,9 @@ export {
|
|
|
37
39
|
formatArticleDate,
|
|
38
40
|
headingSlug,
|
|
39
41
|
mdxComponents,
|
|
42
|
+
mergeSanitizeSchema,
|
|
40
43
|
readingTime,
|
|
44
|
+
settledOnly,
|
|
41
45
|
sortArticles,
|
|
42
46
|
toArticleActions
|
|
43
47
|
};
|
|
@@ -5,15 +5,26 @@
|
|
|
5
5
|
* `agent/**` deliberately ships no renderer of its own, since `agent/** -> content` is
|
|
6
6
|
* lint-blocked by design.
|
|
7
7
|
*
|
|
8
|
-
* LAZY-LOADED: react-markdown
|
|
9
|
-
* `import()` (mirrors `agent/streaming-markdown.tsx` and
|
|
10
|
-
* `basalt-ui/content` never eagerly resolves them. Without
|
|
11
|
-
* raw string as plain text
|
|
8
|
+
* LAZY-LOADED: react-markdown, remark-gfm, rehype-sanitize and remend are all OPTIONAL peers,
|
|
9
|
+
* loaded via `React.lazy` / dynamic `import()` (mirrors `agent/streaming-markdown.tsx` and
|
|
10
|
+
* `./highlighter`) — importing `basalt-ui/content` never eagerly resolves any of them. Without
|
|
11
|
+
* react-markdown or remark-gfm, `Markdown` renders the raw string as plain text; without
|
|
12
|
+
* rehype-sanitize the sanitize pass is skipped (dev-warned once); without remend the streaming
|
|
13
|
+
* tail renders unrepaired.
|
|
14
|
+
*
|
|
15
|
+
* SANITIZATION: basalt appends its own `rehype-sanitize` pass AFTER the consumer's `rehypePlugins`
|
|
16
|
+
* — plugin order in unified is registration order, so last is the only position nothing can
|
|
17
|
+
* outrun. `sanitizeSchema` is an ADDITIONS-only extension merged over `BASALT_SANITIZE_SCHEMA`
|
|
18
|
+
* (see `./sanitize`); removing a default allowance is deliberately not expressible.
|
|
19
|
+
*
|
|
20
|
+
* TRUST vs STREAMING: `streaming` is a rendering mode (the text is still arriving); `contentTrust`
|
|
21
|
+
* is the security input (where the text came from). They are independent — a FINISHED agent message
|
|
22
|
+
* is settled AND untrusted. Only `contentTrust` selects the image allowlist default.
|
|
12
23
|
*
|
|
13
24
|
* Default element overrides:
|
|
14
25
|
* - `h1`..`h6` — slugged + hover-anchored (`./heading-components`).
|
|
15
|
-
* - fenced code (`pre`) —
|
|
16
|
-
* (
|
|
26
|
+
* - fenced code (`pre`) — the fence-renderer registry (`./fence-block`): `fenceRenderers[lang]`,
|
|
27
|
+
* then the built-ins (a settled ` ```mermaid ` fence → `MermaidDiagram`), then `CodeBlock`.
|
|
17
28
|
* - `blockquote` — a GFM alert marker (`[!NOTE]` etc.) renders as `Callout`; otherwise passes
|
|
18
29
|
* through (`./callout-alert`).
|
|
19
30
|
* - `a`/`img` — hardened via `allowedLinkPrefixes`/`allowedImagePrefixes`/`defaultOrigin`
|
|
@@ -32,12 +43,23 @@
|
|
|
32
43
|
* import { Markdown } from 'basalt-ui/content'
|
|
33
44
|
*
|
|
34
45
|
* <Markdown>{articleMarkdown}</Markdown>
|
|
35
|
-
* <Markdown density="chat" streaming
|
|
46
|
+
* <Markdown density="chat" streaming contentTrust="untrusted">{streamedText}</Markdown>
|
|
47
|
+
* <Markdown fenceRenderers={{ vega: settledOnly(({ code }) => <VegaChart spec={code} />) }}>
|
|
36
48
|
*/
|
|
37
49
|
import type { CSSProperties, JSX } from 'react';
|
|
38
50
|
import type { Components } from 'react-markdown';
|
|
51
|
+
import type { FenceRenderers } from './fence-block.js';
|
|
39
52
|
import type { ProseDensity } from './prose.js';
|
|
53
|
+
import type { SanitizeSchemaExtension, SanitizeSchemaInput } from './sanitize.js';
|
|
40
54
|
export type MarkdownComponents = Components;
|
|
55
|
+
export { settledOnly } from './fence-block.js';
|
|
56
|
+
export type { FenceRenderContext, FenceRenderer, FenceRenderers } from './fence-block.js';
|
|
57
|
+
/**
|
|
58
|
+
* Provenance of a `Markdown` body — the ONLY input to the image-allowlist default. Deliberately not
|
|
59
|
+
* a boolean: `contentTrust="untrusted"` says at the call site what it means, where `untrusted` /
|
|
60
|
+
* `!trusted` would not.
|
|
61
|
+
*/
|
|
62
|
+
export type MarkdownContentTrust = 'trusted' | 'untrusted';
|
|
41
63
|
export type MarkdownProps = {
|
|
42
64
|
/** The markdown string to render. Safe to update on every character during streaming. */
|
|
43
65
|
readonly children: string;
|
|
@@ -45,24 +67,89 @@ export type MarkdownProps = {
|
|
|
45
67
|
readonly density?: ProseDensity;
|
|
46
68
|
/** `Prose`'s measure cap. Defaults to `true` for `'article'` density, `false` for `'chat'`. */
|
|
47
69
|
readonly measure?: boolean;
|
|
48
|
-
/** AI-stream mode — block-split + memoize + `remend`-repair the in-flight tail. Default `false`.
|
|
70
|
+
/** AI-stream mode — block-split + memoize + `remend`-repair the in-flight tail. Default `false`.
|
|
71
|
+
* Purely a RENDERING mode: it says the text is still arriving, NOT that it is untrusted. Use
|
|
72
|
+
* `contentTrust` for the security policy. */
|
|
49
73
|
readonly streaming?: boolean;
|
|
50
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Where `children` came from — the input to the image policy, independent of `streaming`.
|
|
76
|
+
* `'untrusted'` (model-generated or third-party markdown) drops the `allowedImagePrefixes`
|
|
77
|
+
* default to same-origin `['/']`; `'trusted'` (your own authored content) keeps
|
|
78
|
+
* `['https://', '/']`. An explicit `allowedImagePrefixes` always wins over both.
|
|
79
|
+
*
|
|
80
|
+
* Default: `'untrusted'` when `streaming` is set, `'trusted'` otherwise. That default only
|
|
81
|
+
* preserves the pre-1.12 fail-safe — it is NOT the policy. Settledness has nothing to do with
|
|
82
|
+
* trust: a FINISHED agent message is still model-generated, so any surface rendering agent text
|
|
83
|
+
* must pin `contentTrust="untrusted"` explicitly rather than lean on `streaming`.
|
|
84
|
+
*/
|
|
85
|
+
readonly contentTrust?: MarkdownContentTrust;
|
|
86
|
+
/**
|
|
87
|
+
* Per-element overrides merged OVER the defaults (only the keys you supply are replaced).
|
|
88
|
+
*
|
|
89
|
+
* A CUSTOM tag admitted via `sanitizeSchema.tagNames` (e.g. `'x-callout'`) cannot be given an
|
|
90
|
+
* override here: react-markdown's `Components` type is a mapped type over `JSX.IntrinsicElements`,
|
|
91
|
+
* which only has entries for real HTML/SVG tags — a made-up tag name is not a valid key of it, so
|
|
92
|
+
* there is no override slot for it to occupy. Style such a tag with CSS (element/attribute
|
|
93
|
+
* selectors) or a wrapping component instead of trying to intercept it here.
|
|
94
|
+
*/
|
|
51
95
|
readonly components?: MarkdownComponents;
|
|
96
|
+
/**
|
|
97
|
+
* Fence renderers keyed by language, consulted BEFORE the built-in mermaid/`CodeBlock` dispatch.
|
|
98
|
+
* Wrap a heavyweight renderer in `settledOnly` to keep it off the still-streaming tail. Pass a
|
|
99
|
+
* referentially stable object — it participates in the streaming memoization.
|
|
100
|
+
*/
|
|
101
|
+
readonly fenceRenderers?: FenceRenderers;
|
|
102
|
+
/**
|
|
103
|
+
* ADDITIONS merged into `BASALT_SANITIZE_SCHEMA` over rehype-sanitize's `defaultSchema`.
|
|
104
|
+
* Removals are not expressible — a schema handed to `rehype-sanitize` directly would replace the
|
|
105
|
+
* defaults wholesale (hast-util-sanitize merges with a shallow top-level spread), which is
|
|
106
|
+
* exactly the footgun this shape removes.
|
|
107
|
+
*/
|
|
108
|
+
readonly sanitizeSchema?: SanitizeSchemaExtension;
|
|
52
109
|
/** Allowed `href` prefixes. Default `['https://', 'mailto:', '#', '/']`. */
|
|
53
110
|
readonly allowedLinkPrefixes?: readonly string[];
|
|
54
|
-
/** Allowed `img src` prefixes. Default `['https://', '/']
|
|
55
|
-
* (same-origin only) — auto-fetched images are the
|
|
56
|
-
* channel, so remote origins must be opted in explicitly
|
|
111
|
+
/** Allowed `img src` prefixes. Default `['https://', '/']` for trusted content, `['/']`
|
|
112
|
+
* (same-origin only) when `contentTrust` resolves to `'untrusted'` — auto-fetched images are the
|
|
113
|
+
* classic prompt-injection exfiltration channel, so remote origins must be opted in explicitly
|
|
114
|
+
* for model-generated content. */
|
|
57
115
|
readonly allowedImagePrefixes?: readonly string[];
|
|
58
116
|
/** Resolves a relative `href`/`src` to an absolute URL before the allowlist check's result is used. */
|
|
59
117
|
readonly defaultOrigin?: string;
|
|
60
118
|
/** Escape hatch — appended after `remark-gfm`. */
|
|
61
119
|
readonly remarkPlugins?: readonly unknown[];
|
|
62
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Escape hatch — appended after react-markdown's defaults, and BEFORE basalt's sanitize pass
|
|
122
|
+
* (which always runs last, so nothing supplied here can outrun it).
|
|
123
|
+
*
|
|
124
|
+
* react-markdown does NOT parse raw HTML in the markdown SOURCE by default (no `rehype-raw` is
|
|
125
|
+
* included here or by react-markdown itself) — a literal `<script>...</script>` typed into
|
|
126
|
+
* `children` never becomes a hast element; it stays inert text and the sanitize pass never even
|
|
127
|
+
* sees it. Concretely: a test that types a raw `<script>` tag into `children` and asserts it never
|
|
128
|
+
* renders is NOT exercising the sanitize pass — it would pass identically with the pass removed
|
|
129
|
+
* entirely, because the string was never a node the sanitizer could act on in the first place. The
|
|
130
|
+
* sanitize pass only ever sees elements produced by remark/rehype PLUGINS (`remarkPlugins`,
|
|
131
|
+
* `rehypePlugins`, or `rehype-raw` if a consumer adds it here) — that is the surface worth testing
|
|
132
|
+
* against unsafe markup, not raw source text.
|
|
133
|
+
*/
|
|
63
134
|
readonly rehypePlugins?: readonly unknown[];
|
|
64
135
|
readonly className?: string;
|
|
65
136
|
readonly style?: CSSProperties;
|
|
66
137
|
};
|
|
67
|
-
|
|
138
|
+
/** The resolved sanitize peer: its plugin plus the `defaultSchema` it re-exports. */
|
|
139
|
+
type MarkdownSanitizer = {
|
|
140
|
+
readonly plugin: unknown;
|
|
141
|
+
readonly baseSchema: SanitizeSchemaInput;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Consumer plugins first, basalt's sanitize pass LAST — "everything after rehype-sanitize could be
|
|
145
|
+
* unsafe", so last is the only position nothing supplied through the escape hatch can outrun.
|
|
146
|
+
*
|
|
147
|
+
* Exported for the ordering test only; `./index.ts` deliberately does not re-export it.
|
|
148
|
+
*/
|
|
149
|
+
export declare function composeRehypePlugins({ sanitizer, consumerPlugins, sanitizeSchema, }: {
|
|
150
|
+
readonly sanitizer: MarkdownSanitizer | null;
|
|
151
|
+
readonly consumerPlugins?: readonly unknown[];
|
|
152
|
+
readonly sanitizeSchema?: SanitizeSchemaExtension;
|
|
153
|
+
}): readonly unknown[];
|
|
154
|
+
export declare function Markdown({ children, density, measure, streaming, contentTrust, components, fenceRenderers, sanitizeSchema, allowedLinkPrefixes, allowedImagePrefixes, defaultOrigin, remarkPlugins, rehypePlugins, className, style, }: MarkdownProps): JSX.Element;
|
|
68
155
|
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/content/markdown.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/content/markdown.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAE/C,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,gBAAgB,CAAA;AAGvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAInD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C,OAAO,KAAK,EAAkB,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAO9F,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAA;AAK3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEtF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,WAAW,CAAA;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAA;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B;;iDAE6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,oBAAoB,CAAA;IAC5C;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAA;IACxC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,uBAAuB,CAAA;IACjD,4EAA4E;IAC5E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChD;;;sCAGkC;IAClC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjD,uGAAuG;IACvG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC3C;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC3C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAC/B,CAAA;AAqED,qFAAqF;AACrF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAA;CACzC,CAAA;AA8ED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,eAAe,EACf,cAAc,GACf,EAAE;IACD,QAAQ,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,uBAAuB,CAAA;CAClD,GAAG,SAAS,OAAO,EAAE,CAKrB;AA2RD,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,OAAmB,EACnB,OAAO,EACP,SAAiB,EAIjB,YAAkD,EAClD,UAAU,EACV,cAAc,EACd,cAAc,EACd,mBAA2C,EAC3C,oBAA0D,EAC1D,aAAa,EACb,aAAa,EACb,aAAa,EACb,SAAS,EACT,KAAK,GACN,EAAE,aAAa,eAiCf"}
|