@molecule/app-markdown 1.0.0 → 1.0.1
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/README.md +224 -0
- package/package.json +10 -4
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-08-04T01:52:06.046Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/app-markdown
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
Markdown rendering core interface for molecule.dev.
|
|
16
|
+
|
|
17
|
+
Provides a standardized API for rendering markdown content into HTML,
|
|
18
|
+
with support for GFM and table of contents extraction.
|
|
19
|
+
Bond a provider (e.g. `@molecule/app-markdown-react-markdown`) to supply
|
|
20
|
+
the concrete implementation.
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { requireProvider, setProvider } from '@molecule/app-markdown'
|
|
26
|
+
import { provider } from '@molecule/app-markdown-react-markdown'
|
|
27
|
+
|
|
28
|
+
setProvider(provider) // once, at startup (bonds.ts)
|
|
29
|
+
|
|
30
|
+
const result = requireProvider().render('# Hello World', { gfm: true })
|
|
31
|
+
console.log(result.html) // sanitized HTML string
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Type
|
|
35
|
+
|
|
36
|
+
`core`
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @molecule/app-markdown @molecule/app-bond
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### Interfaces
|
|
47
|
+
|
|
48
|
+
#### `MarkdownOptions`
|
|
49
|
+
|
|
50
|
+
Options for markdown rendering.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
interface MarkdownOptions {
|
|
54
|
+
/** Whether to sanitize the rendered HTML to prevent XSS. Defaults to `true`. */
|
|
55
|
+
sanitize?: boolean
|
|
56
|
+
|
|
57
|
+
/** Whether to enable GitHub Flavored Markdown extensions. Defaults to `true`. */
|
|
58
|
+
gfm?: boolean
|
|
59
|
+
|
|
60
|
+
/** Whether to convert line breaks to `<br>` elements. Defaults to `false`. */
|
|
61
|
+
breaks?: boolean
|
|
62
|
+
|
|
63
|
+
/** Custom component overrides keyed by HTML element name. */
|
|
64
|
+
components?: Record<string, unknown>
|
|
65
|
+
|
|
66
|
+
/** Target attribute for rendered links. */
|
|
67
|
+
linkTarget?: '_blank' | '_self'
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `MarkdownProvider`
|
|
72
|
+
|
|
73
|
+
Markdown rendering provider interface.
|
|
74
|
+
|
|
75
|
+
All markdown providers must implement this interface to render
|
|
76
|
+
markdown strings into HTML output with optional features.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
interface MarkdownProvider {
|
|
80
|
+
/** Provider name identifier. */
|
|
81
|
+
readonly name: string
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Renders a markdown string into HTML.
|
|
85
|
+
*
|
|
86
|
+
* @param markdown - The markdown source string to render.
|
|
87
|
+
* @param options - Optional rendering configuration.
|
|
88
|
+
* @returns The rendered HTML and optional table of contents.
|
|
89
|
+
*/
|
|
90
|
+
render(markdown: string, options?: MarkdownOptions): RenderedMarkdown
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### `RenderedMarkdown`
|
|
95
|
+
|
|
96
|
+
Result of rendering markdown content.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
interface RenderedMarkdown {
|
|
100
|
+
/** The rendered HTML string. */
|
|
101
|
+
html: string
|
|
102
|
+
|
|
103
|
+
/** Optional table of contents extracted from headings. */
|
|
104
|
+
toc?: TocEntry[]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### `TocEntry`
|
|
109
|
+
|
|
110
|
+
Table of contents entry extracted from markdown headings.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
interface TocEntry {
|
|
114
|
+
/** Unique identifier for the heading (slug). */
|
|
115
|
+
id: string
|
|
116
|
+
|
|
117
|
+
/** Text content of the heading. */
|
|
118
|
+
text: string
|
|
119
|
+
|
|
120
|
+
/** Heading level (1-6). */
|
|
121
|
+
level: number
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Functions
|
|
126
|
+
|
|
127
|
+
#### `getProvider()`
|
|
128
|
+
|
|
129
|
+
Retrieves the bonded markdown provider, or `null` if none is bonded.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
function getProvider(): MarkdownProvider | null
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Returns:** The active markdown provider, or `null`.
|
|
136
|
+
|
|
137
|
+
#### `hasProvider()`
|
|
138
|
+
|
|
139
|
+
Checks whether a markdown provider has been bonded.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
function hasProvider(): boolean
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Returns:** `true` if a markdown provider is available.
|
|
146
|
+
|
|
147
|
+
#### `requireProvider()`
|
|
148
|
+
|
|
149
|
+
Retrieves the bonded markdown provider, throwing if none is configured.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
function requireProvider(): MarkdownProvider
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Returns:** The active markdown provider.
|
|
156
|
+
|
|
157
|
+
#### `setProvider(provider)`
|
|
158
|
+
|
|
159
|
+
Registers a markdown provider as the active singleton.
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
function setProvider(provider: MarkdownProvider): void
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- `provider` — The markdown provider implementation to bond.
|
|
166
|
+
|
|
167
|
+
## Available Providers
|
|
168
|
+
|
|
169
|
+
| Provider | Package |
|
|
170
|
+
| -------- | --------------------------------------- |
|
|
171
|
+
| Markdown | `@molecule/app-markdown-react-markdown` |
|
|
172
|
+
|
|
173
|
+
## Injection Notes
|
|
174
|
+
|
|
175
|
+
### Requirements
|
|
176
|
+
|
|
177
|
+
Peer dependencies:
|
|
178
|
+
|
|
179
|
+
- `@molecule/app-bond` ^1.0.1
|
|
180
|
+
|
|
181
|
+
### Runtime Dependencies
|
|
182
|
+
|
|
183
|
+
- `@molecule/app-bond`
|
|
184
|
+
|
|
185
|
+
- **Wire a bond at startup** — {@link requireProvider} throws until
|
|
186
|
+
`setProvider(provider)` has been called.
|
|
187
|
+
- **`sanitize` defaults to `true` and is the XSS gate.** The result is an
|
|
188
|
+
HTML STRING you inject via your framework's raw-HTML mechanism — that is
|
|
189
|
+
only safe because it was sanitized. NEVER pass `sanitize: false` for
|
|
190
|
+
user-supplied or model-generated markdown (chat replies, comments, notes);
|
|
191
|
+
reserve it for fully trusted, app-authored content.
|
|
192
|
+
- Options are per-call (`gfm`, `breaks`, `linkTarget`); `result.toc` carries
|
|
193
|
+
extracted headings when the provider supports it. Syntax highlighting is a
|
|
194
|
+
provider concern — e.g. the react-markdown bond wires a rehype highlighter
|
|
195
|
+
via its `rehypePlugins` config rather than a generic option.
|
|
196
|
+
|
|
197
|
+
## E2E Tests
|
|
198
|
+
|
|
199
|
+
Integration checklist — drive the real UI (live preview, no mocks), adapt
|
|
200
|
+
each item to this app's actual screens/flows, and check every box off one
|
|
201
|
+
by one. A box you can't check is an integration bug to fix — not a skip:
|
|
202
|
+
|
|
203
|
+
- [ ] Common markdown renders as real HTML wherever the app shows it (chat
|
|
204
|
+
reply, comment, note, README preview): `#`..`######` become `<h1>`..`<h6>`,
|
|
205
|
+
`**bold**` a `<strong>`, `*italic*` an `<em>`, `-`/`1.` lists become
|
|
206
|
+
`<ul>`/`<ol>` of `<li>`, `[text](url)` an `<a>` anchor, and a fenced code
|
|
207
|
+
block a `<pre><code>` — not the raw `*`/backticks shown as literal text.
|
|
208
|
+
- [ ] GFM extras render when enabled (`gfm`, default on): a pipe table
|
|
209
|
+
`| a | b |` becomes a real `<table>` with header + rows, and ``
|
|
210
|
+
an `<img>`.
|
|
211
|
+
- [ ] The output tracks the source: editing the markdown updates the preview
|
|
212
|
+
live — change a heading's text and its `<h#>` updates; add a list item and
|
|
213
|
+
a new `<li>` appears. No stale or one-shot render.
|
|
214
|
+
- [ ] SECURITY (XSS) — user- or model-supplied markdown is sanitized
|
|
215
|
+
(`sanitize`, default on, the XSS gate): markdown containing a raw
|
|
216
|
+
`<script>alert(1)</script>`, an `<img src=x onerror=alert(1)>`, or a
|
|
217
|
+
`[click](javascript:alert(1))` link must NOT execute and must NOT produce
|
|
218
|
+
active markup — the script is stripped, the `onerror` is gone, and the
|
|
219
|
+
link's `href` is neutralized. Verify in the browser: no alert fires, and
|
|
220
|
+
DevTools shows no `<script>`, `onerror`, or `javascript:` in the rendered
|
|
221
|
+
DOM. Never render untrusted content with `sanitize: false`.
|
|
222
|
+
- [ ] Malformed markdown degrades gracefully — an unclosed `**`, a broken
|
|
223
|
+
`[link](`, or a half-open code fence renders as readable text and never
|
|
224
|
+
throws, blanks the view, or breaks the surrounding page.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-markdown",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,18 +17,24 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"keywords": [
|
|
23
24
|
"molecule",
|
|
24
25
|
"markdown"
|
|
25
26
|
],
|
|
26
27
|
"license": "Apache-2.0",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/molecule-dev/molecule.git",
|
|
31
|
+
"directory": "packages/app/core/markdown"
|
|
32
|
+
},
|
|
27
33
|
"peerDependencies": {
|
|
28
|
-
"@molecule/app-bond": "^1.0.
|
|
34
|
+
"@molecule/app-bond": "^1.0.1"
|
|
29
35
|
},
|
|
30
36
|
"devDependencies": {
|
|
31
|
-
"@molecule/app-bond": "1.0.
|
|
37
|
+
"@molecule/app-bond": "1.0.1",
|
|
32
38
|
"@types/node": "26.1.2",
|
|
33
39
|
"typescript": "6.0.3",
|
|
34
40
|
"vitest": "4.1.10"
|