@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.
Files changed (2) hide show
  1. package/README.md +224 -0
  2. 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 `![alt](src)`
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.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.0"
34
+ "@molecule/app-bond": "^1.0.1"
29
35
  },
30
36
  "devDependencies": {
31
- "@molecule/app-bond": "1.0.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"