feat(knowledge): add markdown rendering (KNOW-004)
- Install marked, marked-highlight, marked-gfm-heading-id, sanitize-html - Create markdown utility with GFM support (tables, task lists, strikethrough) - Add code syntax highlighting with highlight.js - Implement XSS sanitization for security - Update knowledge service to use markdown renderer - Add comprehensive test suite (34 tests, all passing) - Generate IDs for headers for deep linking - Cache rendered HTML in database for performance
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
# Knowledge Module Utilities
|
||||
|
||||
## Markdown Rendering
|
||||
|
||||
### Overview
|
||||
|
||||
The `markdown.ts` utility provides secure markdown rendering with GFM (GitHub Flavored Markdown) support, syntax highlighting, and XSS protection.
|
||||
|
||||
### Features
|
||||
|
||||
- **GFM Support**: Tables, task lists, strikethrough, autolinks
|
||||
- **Syntax Highlighting**: Code blocks with language detection via highlight.js
|
||||
- **XSS Protection**: HTML sanitization using sanitize-html
|
||||
- **Header IDs**: Automatic ID generation for headers (for linking)
|
||||
- **Security**: Blocks dangerous HTML (scripts, iframes, event handlers)
|
||||
|
||||
### Usage
|
||||
|
||||
```typescript
|
||||
import { renderMarkdown, markdownToPlainText } from './utils/markdown';
|
||||
|
||||
// Render markdown to HTML (async)
|
||||
const html = await renderMarkdown('# Hello **World**');
|
||||
// Result: <h1 id="hello-world">Hello <strong>World</strong></h1>
|
||||
|
||||
// Extract plain text (for search indexing)
|
||||
const plainText = await markdownToPlainText('# Hello **World**');
|
||||
// Result: "Hello World"
|
||||
```
|
||||
|
||||
### Supported Markdown Features
|
||||
|
||||
#### Basic Formatting
|
||||
- **Bold**: `**text**` or `__text__`
|
||||
- *Italic*: `*text*` or `_text_`
|
||||
- ~~Strikethrough~~: `~~text~~`
|
||||
- `Inline code`: `` `code` ``
|
||||
|
||||
#### Headers
|
||||
```markdown
|
||||
# H1
|
||||
## H2
|
||||
### H3
|
||||
```
|
||||
|
||||
#### Lists
|
||||
```markdown
|
||||
- Unordered list
|
||||
- Nested item
|
||||
|
||||
1. Ordered list
|
||||
2. Another item
|
||||
```
|
||||
|
||||
#### Task Lists
|
||||
```markdown
|
||||
- [ ] Unchecked task
|
||||
- [x] Completed task
|
||||
```
|
||||
|
||||
#### Tables
|
||||
```markdown
|
||||
| Header 1 | Header 2 |
|
||||
|----------|----------|
|
||||
| Cell 1 | Cell 2 |
|
||||
```
|
||||
|
||||
#### Code Blocks
|
||||
````markdown
|
||||
```typescript
|
||||
const greeting: string = "Hello";
|
||||
console.log(greeting);
|
||||
```
|
||||
````
|
||||
|
||||
#### Links and Images
|
||||
```markdown
|
||||
[Link text](https://example.com)
|
||||

|
||||
```
|
||||
|
||||
#### Blockquotes
|
||||
```markdown
|
||||
> This is a quote
|
||||
> Multi-line quote
|
||||
```
|
||||
|
||||
### Security
|
||||
|
||||
The renderer implements multiple layers of security:
|
||||
|
||||
1. **HTML Sanitization**: Only allows safe HTML tags and attributes
|
||||
2. **URL Validation**: Blocks `javascript:` and other dangerous protocols
|
||||
3. **External Links**: Automatically adds `target="_blank"` and `rel="noopener noreferrer"`
|
||||
4. **Task Lists**: Checkboxes are disabled to prevent interaction
|
||||
5. **No Event Handlers**: Blocks `onclick`, `onload`, etc.
|
||||
6. **No Dangerous Tags**: Blocks `<script>`, `<iframe>`, `<object>`, `<embed>`
|
||||
|
||||
### Testing
|
||||
|
||||
Comprehensive test suite covers:
|
||||
- Basic markdown rendering
|
||||
- GFM features (tables, task lists, strikethrough)
|
||||
- Code syntax highlighting
|
||||
- Security (XSS prevention)
|
||||
- Edge cases (unicode, long content, nested structures)
|
||||
|
||||
Run tests:
|
||||
```bash
|
||||
pnpm test --filter=@mosaic/api -- markdown.spec.ts
|
||||
```
|
||||
|
||||
### Integration
|
||||
|
||||
The markdown renderer is integrated into the Knowledge Entry service:
|
||||
|
||||
1. **On Create**: Renders `content` to `contentHtml`
|
||||
2. **On Update**: Re-renders if content changes
|
||||
3. **Caching**: HTML is stored in database for performance
|
||||
|
||||
See `knowledge.service.ts` for implementation details.
|
||||
Reference in New Issue
Block a user