safe-mdx 1.5.0 → 1.7.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/README.md +94 -8
- package/dist/dynamic-esm-component.d.ts +1 -1
- package/dist/dynamic-esm-component.d.ts.map +1 -1
- package/dist/dynamic-esm-component.js +9 -1
- package/dist/dynamic-esm-component.js.map +1 -1
- package/dist/esm-parser.d.ts +1 -1
- package/dist/esm-parser.d.ts.map +1 -1
- package/dist/esm-parser.js +3 -3
- package/dist/esm-parser.js.map +1 -1
- package/dist/esm-parser.test.js +2 -2
- package/dist/html/html-and-md.test.js.map +1 -1
- package/dist/html/html-to-mdx-ast.d.ts +1 -1
- package/dist/html/html-to-mdx-ast.js +4 -4
- package/dist/html/html-to-mdx-ast.js.map +1 -1
- package/dist/html/html-to-mdx-ast.test.js +3 -3
- package/dist/html/html-to-mdx-ast.test.js.map +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +5 -1
- package/dist/parse.js.map +1 -1
- package/dist/safe-mdx.bench.js +2 -2
- package/dist/safe-mdx.bench.js.map +1 -1
- package/dist/safe-mdx.d.ts +48 -3
- package/dist/safe-mdx.d.ts.map +1 -1
- package/dist/safe-mdx.js +219 -26
- package/dist/safe-mdx.js.map +1 -1
- package/dist/safe-mdx.test.js +420 -5
- package/dist/safe-mdx.test.js.map +1 -1
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +3 -1
- package/dist/streaming.js.map +1 -1
- package/package.json +30 -7
- package/src/esm-parser.test.ts +3 -3
- package/src/esm-parser.ts +4 -4
- package/src/html/html-and-md.test.ts +2 -2
- package/src/html/html-to-mdx-ast.test.ts +3 -3
- package/src/html/html-to-mdx-ast.ts +4 -4
- package/src/parse.ts +3 -1
- package/src/safe-mdx.bench.tsx +2 -2
- package/src/safe-mdx.test.tsx +519 -11
- package/src/safe-mdx.tsx +315 -28
- package/src/streaming.tsx +2 -1
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "safe-mdx",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"
|
|
5
|
-
"description": "Render MDX in React without eval",
|
|
6
|
-
"repository": "https://github.com/holocron-hq/safe-mdx",
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Render MDX in React without eval, works in Cloudflare Workers and Vercel Edge",
|
|
7
5
|
"type": "module",
|
|
6
|
+
"main": "./dist/safe-mdx.js",
|
|
8
7
|
"types": "./dist/safe-mdx.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/holocron-hq/safe-mdx"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/holocron-hq/safe-mdx",
|
|
13
|
+
"bugs": "https://github.com/holocron-hq/safe-mdx/issues",
|
|
9
14
|
"exports": {
|
|
15
|
+
"./package.json": "./package.json",
|
|
10
16
|
".": {
|
|
11
17
|
"types": "./dist/safe-mdx.d.ts",
|
|
12
18
|
"default": "./dist/safe-mdx.js"
|
|
@@ -24,15 +30,29 @@
|
|
|
24
30
|
"browser": "./dist/html/domparser-browser.js",
|
|
25
31
|
"default": "./dist/html/domparser.js"
|
|
26
32
|
},
|
|
27
|
-
"./src
|
|
28
|
-
|
|
33
|
+
"./src": {
|
|
34
|
+
"types": "./src/safe-mdx.tsx",
|
|
35
|
+
"default": "./src/safe-mdx.tsx"
|
|
36
|
+
},
|
|
37
|
+
"./src/*": {
|
|
38
|
+
"types": "./src/*.tsx",
|
|
39
|
+
"default": "./src/*.tsx"
|
|
40
|
+
}
|
|
29
41
|
},
|
|
30
42
|
"files": [
|
|
31
43
|
"dist",
|
|
32
44
|
"src"
|
|
33
45
|
],
|
|
34
46
|
"keywords": [
|
|
35
|
-
"mdx"
|
|
47
|
+
"mdx",
|
|
48
|
+
"react",
|
|
49
|
+
"server-components",
|
|
50
|
+
"rsc",
|
|
51
|
+
"safe",
|
|
52
|
+
"no-eval",
|
|
53
|
+
"cloudflare-workers",
|
|
54
|
+
"edge",
|
|
55
|
+
"markdown"
|
|
36
56
|
],
|
|
37
57
|
"author": "remorses <beats.by.morse@gmail.com>",
|
|
38
58
|
"license": "MIT",
|
|
@@ -59,6 +79,7 @@
|
|
|
59
79
|
"@changesets/cli": "^2.28.1",
|
|
60
80
|
"@tailwindcss/typography": "^0.5.16",
|
|
61
81
|
"@tailwindcss/vite": "^4.1.11",
|
|
82
|
+
"@types/escodegen": "^0.0.10",
|
|
62
83
|
"@types/estree-jsx": "^1.0.5",
|
|
63
84
|
"@types/mdast": "^4.0.0",
|
|
64
85
|
"@types/node": "^22.15.17",
|
|
@@ -68,12 +89,14 @@
|
|
|
68
89
|
"@vitejs/plugin-react": "^4.7.0",
|
|
69
90
|
"@vitest/coverage-v8": "^1.6.0",
|
|
70
91
|
"dedent": "^1.5.1",
|
|
92
|
+
"escodegen": "^2.1.0",
|
|
71
93
|
"importmap-vite-plugin": "^0.0.0",
|
|
72
94
|
"mdast-util-mdx-jsx": "^3.2.0",
|
|
73
95
|
"react": "^19.2.1",
|
|
74
96
|
"react-dom": "^19.2.1",
|
|
75
97
|
"remark-parse": "^11.0.0",
|
|
76
98
|
"remark-stringify": "^11.0.0",
|
|
99
|
+
"rimraf": "^6.0.1",
|
|
77
100
|
"tailwindcss": "^4.1.11",
|
|
78
101
|
"typescript": "5.8.3",
|
|
79
102
|
"vite": "^6.2.6",
|
package/src/esm-parser.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expect, test, describe } from 'vitest'
|
|
2
|
-
import { parseEsmImports, extractComponentInfo } from './esm-parser.
|
|
3
|
-
import { mdxParse, extractImports, resolveModulePath } from './parse.
|
|
4
|
-
import type { SafeMdxError } from './safe-mdx.
|
|
2
|
+
import { parseEsmImports, extractComponentInfo } from './esm-parser.ts'
|
|
3
|
+
import { mdxParse, extractImports, resolveModulePath } from './parse.ts'
|
|
4
|
+
import type { SafeMdxError } from './safe-mdx.tsx'
|
|
5
5
|
|
|
6
6
|
describe('parseEsmImports', () => {
|
|
7
7
|
test('parses default imports from HTTPS URLs', () => {
|
package/src/esm-parser.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SafeMdxError } from './safe-mdx.
|
|
1
|
+
import type { SafeMdxError } from './safe-mdx.tsx'
|
|
2
2
|
|
|
3
3
|
export interface ParsedImport {
|
|
4
4
|
componentName: string
|
|
@@ -83,9 +83,9 @@ export function parseEsmImports(
|
|
|
83
83
|
* Extracts component info from an import map entry
|
|
84
84
|
*/
|
|
85
85
|
export function extractComponentInfo(importInfo: string): { importUrl: string; componentName: string } {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
const parts = importInfo.split('#')
|
|
87
|
+
const importUrl = parts[0] ?? importInfo
|
|
88
|
+
const componentName = importInfo.includes('#') ? (parts[1] ?? 'default') : 'default'
|
|
89
89
|
|
|
90
90
|
return { importUrl, componentName }
|
|
91
91
|
}
|
|
@@ -55,7 +55,7 @@ async function htmlToMdxString({
|
|
|
55
55
|
parent &&
|
|
56
56
|
typeof index === 'number'
|
|
57
57
|
) {
|
|
58
|
-
const htmlValue = node.value
|
|
58
|
+
const htmlValue = node.value
|
|
59
59
|
|
|
60
60
|
// Parse HTML to MDX AST with processor for markdown parsing
|
|
61
61
|
const mdxNodes = parseHtmlToMdxAst({
|
|
@@ -77,7 +77,7 @@ async function htmlToMdxString({
|
|
|
77
77
|
|
|
78
78
|
// Replace the HTML node with the MDX nodes
|
|
79
79
|
if (mdxNodes.length === 1) {
|
|
80
|
-
parent.children[index] = mdxNodes[0]
|
|
80
|
+
parent.children[index] = mdxNodes[0]!
|
|
81
81
|
} else if (mdxNodes.length > 1) {
|
|
82
82
|
parent.children.splice(index, 1, ...mdxNodes)
|
|
83
83
|
} else {
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
parseHtmlToMdxAst,
|
|
6
6
|
htmlToMdxAst,
|
|
7
7
|
remarkMdxJsxNormalize,
|
|
8
|
-
} from './html-to-mdx-ast.
|
|
8
|
+
} from './html-to-mdx-ast.ts'
|
|
9
9
|
import { unified } from 'unified'
|
|
10
10
|
import remarkMdx from 'remark-mdx'
|
|
11
11
|
import remarkStringify from 'remark-stringify'
|
|
12
12
|
import remarkParse from 'remark-parse'
|
|
13
13
|
import type { RootContent } from 'mdast'
|
|
14
|
-
import { mdxParse } from '../parse.
|
|
15
|
-
import { MdastToJsx } from '../safe-mdx.
|
|
14
|
+
import { mdxParse } from '../parse.ts'
|
|
15
|
+
import { MdastToJsx } from '../safe-mdx.tsx'
|
|
16
16
|
|
|
17
17
|
// Default components for testing
|
|
18
18
|
const components = {
|
|
@@ -6,9 +6,9 @@ import type {
|
|
|
6
6
|
} from 'mdast-util-mdx-jsx'
|
|
7
7
|
import type { Processor } from 'unified'
|
|
8
8
|
import { unified } from 'unified'
|
|
9
|
-
import { convertAttributeNameToJSX } from './convert-attributes.
|
|
10
|
-
import { parseHTML } from './domparser.
|
|
11
|
-
import { remarkMdxJsxNormalize } from './remark-mdx-jsx-normalize.
|
|
9
|
+
import { convertAttributeNameToJSX } from './convert-attributes.ts'
|
|
10
|
+
import { parseHTML } from './domparser.ts'
|
|
11
|
+
import { remarkMdxJsxNormalize } from './remark-mdx-jsx-normalize.ts'
|
|
12
12
|
|
|
13
13
|
// Re-export the normalize plugin
|
|
14
14
|
export { remarkMdxJsxNormalize }
|
|
@@ -77,7 +77,7 @@ function deindent(text: string): string {
|
|
|
77
77
|
for (const line of lines) {
|
|
78
78
|
if (line.trim()) {
|
|
79
79
|
const match = line.match(/^(\s*)/)
|
|
80
|
-
if (match) {
|
|
80
|
+
if (match?.[1] != null) {
|
|
81
81
|
minIndent = Math.min(minIndent, match[1].length)
|
|
82
82
|
}
|
|
83
83
|
}
|
package/src/parse.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Root, RootContent } from 'mdast'
|
|
|
5
5
|
import { remark } from 'remark'
|
|
6
6
|
import remarkGfm from 'remark-gfm'
|
|
7
7
|
import remarkMdx from 'remark-mdx'
|
|
8
|
-
import { parseHtmlToMdxAst, remarkMdxJsxNormalize } from './html/html-to-mdx-ast.
|
|
8
|
+
import { parseHtmlToMdxAst, remarkMdxJsxNormalize } from './html/html-to-mdx-ast.ts'
|
|
9
9
|
|
|
10
10
|
export { parseHtmlToMdxAst, remarkMdxJsxNormalize }
|
|
11
11
|
|
|
@@ -95,6 +95,7 @@ export function remarkMarkAndUnravel() {
|
|
|
95
95
|
|
|
96
96
|
while (++offset < children.length) {
|
|
97
97
|
const child = children[offset]
|
|
98
|
+
if (!child) continue
|
|
98
99
|
|
|
99
100
|
if (
|
|
100
101
|
child.type === 'mdxJsxTextElement' ||
|
|
@@ -122,6 +123,7 @@ export function remarkMarkAndUnravel() {
|
|
|
122
123
|
|
|
123
124
|
while (++offset < children.length) {
|
|
124
125
|
const child = children[offset]
|
|
126
|
+
if (!child) continue
|
|
125
127
|
|
|
126
128
|
if (child.type === 'mdxJsxTextElement') {
|
|
127
129
|
// @ts-expect-error: mutate because it is faster; content model is fine.
|
package/src/safe-mdx.bench.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bench, describe } from 'vitest'
|
|
2
|
-
import { mdxParse } from './parse.
|
|
3
|
-
import { MdastToJsx } from './safe-mdx.
|
|
2
|
+
import { mdxParse } from './parse.ts'
|
|
3
|
+
import { MdastToJsx } from './safe-mdx.tsx'
|
|
4
4
|
|
|
5
5
|
let longMdxContent = await fetch(
|
|
6
6
|
'https://raw.githubusercontent.com/colinhacks/zod/0a49fa39348b7c72b19ddedc3b0f879bd395304b/packages/docs/content/packages/v3.mdx',
|