npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@norkive/mdx-safe-processor

v1.0.0

Published

Safe MDX content processor with XSS prevention, link transformation, and code block protection. Functional programming architecture.

Downloads

9

Readme

@norkive/mdx-safe-processor

npm version License TypeScript

Safe MDX content processor with XSS prevention, link transformation, and code block protection. Built with functional programming architecture for maximum reusability and testability.

✨ Features

  • 🛡️ XSS Prevention: Strict HTML tag whitelist with attribute validation
  • 🔗 Link Transformation: Automatic conversion of YouTube, files, Google Drive, bookmarks, and embeds
  • 📝 Code Block Protection: Preserves code blocks and blockquotes during processing
  • 🎨 Markdown Syntax Conversion: Converts bold, italic, and inline code to HTML
  • 🔒 Safe HTML Sanitization: Removes unsafe tags and attributes
  • 🔄 Functional Pipeline: Pure functions with pipeline pattern for easy composition
  • 📦 Zero Dependencies: Lightweight package with no external dependencies
  • 🎯 TypeScript: Full type definitions included

📦 Installation

npm install @norkive/mdx-safe-processor
# or
yarn add @norkive/mdx-safe-processor
# or
pnpm add @norkive/mdx-safe-processor

🚀 Quick Start

import {
  processMdxContentFn,
  decodeUrlEncodedLinks,
  validateAndFixMdxContent,
} from '@norkive/mdx-safe-processor';

// Basic usage
const processed = processMdxContentFn(mdxContent);

// With URL decoding
const decoded = decodeUrlEncodedLinks(mdxContent);
const processed = processMdxContentFn(decoded);

// With validation
const result = await validateAndFixMdxContent(mdxContent, 'my-file.mdx');
if (result.isValid) {
  console.log('Processed content:', result.content);
} else {
  console.error('Errors:', result.errors);
}

📖 API Reference

processMdxContentFn(content: string): string

Main processing function that transforms MDX content safely.

Parameters:

  • content - Raw MDX content string

Returns:

  • Processed MDX content string

Example:

const processed = processMdxContentFn(`
# Hello World

[video](https://www.youtube.com/watch?v=dQw4w9WgXcQ)

\`\`\`javascript
console.log('code block');
\`\`\`
`);

decodeUrlEncodedLinks(content: string): string

Decodes URL-encoded link text in markdown links.

Parameters:

  • content - MDX content with URL-encoded links

Returns:

  • Content with decoded link text

Example:

const decoded = decodeUrlEncodedLinks('[Hello%20World](url)');
// Returns: '[Hello World](url)'

validateAndFixMdxContent(content: string, filename?: string): Promise<MdxValidationResult>

Validates and fixes MDX content, returning validation result.

Parameters:

  • content - MDX content to validate
  • filename - Optional filename for error reporting (default: "unknown")

Returns:

  • Promise resolving to MdxValidationResult:
    {
      isValid: boolean;
      content: string;
      errors: string[];
    }

Example:

const result = await validateAndFixMdxContent(mdxContent, 'post.mdx');
if (result.isValid) {
  // Use result.content
} else {
  // Handle errors
  console.error(result.errors);
}

processMdxContentWithLoggingFn(content: string): string

Processes MDX content with console logging for debugging.

Parameters:

  • content - Raw MDX content string

Returns:

  • Processed MDX content string

Example:

const processed = processMdxContentWithLoggingFn(mdxContent);
// Logs: "🔄 MDX 처리 시작...", "📝 링크 변환 중...", etc.

convertUnsafeTags(content: string): string

Alias for processMdxContentFn - converts unsafe HTML tags to HTML entities.

🔧 Link Transformation

The processor automatically transforms various link types:

YouTube Links

[video](https://www.youtube.com/watch?v=xxx)

<YoutubeWrapper names={"video"} urls={"https://www.youtube.com/watch?v=xxx"} />

File Links

[document.pdf](https://example.com/file.pdf)

<FileWrapper names={"document.pdf"} urls={"https://example.com/file.pdf"} />

Google Drive Links

[My Doc](https://drive.google.com/file/d/xxx)

<GoogleDriveWrapper names={"My Doc"} urls={"https://drive.google.com/file/d/xxx"} />

Embed Links

[embed](https://example.com)

<EmbededWrapper names={"embed"} urls={"https://example.com"} />

Bookmark Links

[bookmark](https://example.com)

<BookMarkWrapper names={"bookmark"} urls={"https://example.com"} />

🛡️ Security Features

XSS Prevention

The processor uses a strict whitelist of allowed HTML tags:

  • Basic structure: h1-h6, p, span, div, br, hr
  • Text styling: strong, b, em, i, u, s, etc.
  • Links and quotes: a, blockquote, cite
  • Code: code, pre, kbd, samp, var
  • Lists: ul, ol, li, dl, dt, dd
  • Tables: table, thead, tbody, tr, td, th
  • Media: img, video, audio, figure
  • Custom components: YoutubeWrapper, FileWrapper, etc.

Allowed JSX Attributes

  • Basic: className, id, style
  • Links: src, href, alt, target, rel
  • Forms: value, type, placeholder, disabled, etc.
  • Accessibility: All data-* and aria-* attributes

Any tag or attribute not in the whitelist is converted to HTML entities for safety.

🏗️ Architecture

Functional Programming

The processor uses functional programming principles:

  • Pure Functions: No side effects, predictable output
  • Pipeline Pattern: Data flows through transformation steps
  • Function Composition: Small functions combined into complex logic
  • Immutability: Original content is never modified

Processing Pipeline

Input MDX
  ↓
1. Link Transformation (YouTube, files, embeds, etc.)
  ↓
2. Code Block Protection (temporary markers)
  ↓
3. Blockquote Protection (temporary markers)
  ↓
4. Table Block Fixing
  ↓
5. Heading Block Fixing
  ↓
6. Markdown Syntax Conversion (bold, italic, code)
  ↓
7. Unclosed Tag Fixing
  ↓
8. Unsafe Tag Sanitization (XSS prevention)
  ↓
9. Protected Content Restoration
  ↓
10. HTML Entity Decoding
  ↓
11. MDX Extension Removal
  ↓
Output MDX

📊 Performance

  • Bundle Size: ~15 KB (minified)
  • Zero Dependencies: No external runtime dependencies
  • Tree Shakeable: ESM support for optimal bundling
  • Type Safe: Full TypeScript support

🧪 Example Usage

Basic Processing

import { processMdxContentFn } from '@norkive/mdx-safe-processor';

const mdxContent = `
# My Post

This is **bold** and *italic* text.

[video](https://www.youtube.com/watch?v=dQw4w9WgXcQ)

\`\`\`javascript
const code = 'preserved';
\`\`\`
`;

const processed = processMdxContentFn(mdxContent);

With Validation

import { validateAndFixMdxContent } from '@norkive/mdx-safe-processor';

const result = await validateAndFixMdxContent(mdxContent, 'post.mdx');

if (result.isValid) {
  // Use processed content
  console.log(result.content);
} else {
  // Handle errors
  console.error('Validation errors:', result.errors);
}

Complete Pipeline

import {
  decodeUrlEncodedLinks,
  processMdxContentFn,
} from '@norkive/mdx-safe-processor';

// Step 1: Decode URL-encoded links
const decoded = decodeUrlEncodedLinks(rawMdxContent);

// Step 2: Process content
const processed = processMdxContentFn(decoded);

// Use processed content

🔗 Related Packages

📝 License

MIT

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📧 Author

Ryoon with Wisdom Lights

🔗 Links


Made with ❤️ by Ryoon with Wisdom Lights