Socket
Socket
Sign inDemoInstall

@mdx-js/mdx

Package Overview
Dependencies
Maintainers
4
Versions
210
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mdx-js/mdx - npm Package Compare versions

Comparing version 1.6.3 to 2.0.0-next.0

4

index.js
const unified = require('unified')
const toMDAST = require('remark-parse')
const remarkMdx = require('remark-mdx')
const remarkMdxJs = require('remark-mdxjs')
const footnotes = require('remark-footnotes')

@@ -8,3 +9,2 @@ const squeeze = require('remark-squeeze-paragraphs')

const raw = require('hast-util-raw')
const toMDXAST = require('./md-ast-to-mdx-ast')
const mdxAstToMdxHast = require('./mdx-ast-to-mdx-hast')

@@ -34,5 +34,5 @@ const mdxHastToJsx = require('./mdx-hast-to-jsx')

.use(remarkMdx, options)
.use(remarkMdxJs, options)
.use(footnotes, options)
.use(squeeze, options)
.use(toMDXAST, options)

@@ -39,0 +39,0 @@ plugins.forEach(plugin => {

const toHAST = require('mdast-util-to-hast')
const all = require('mdast-util-to-hast/lib/all')
const detab = require('detab')

@@ -64,2 +65,3 @@ const u = require('unist-builder')

},
// To do: rename to `mdxJsImport`
import(h, node) {

@@ -70,2 +72,3 @@ return Object.assign({}, node, {

},
// To do: rename to `mdxJsExport`
export(h, node) {

@@ -76,10 +79,16 @@ return Object.assign({}, node, {

},
comment(h, node) {
mdxBlockElement(h, node) {
return Object.assign({}, node, {children: all(h, node)})
},
mdxSpanElement(h, node) {
return Object.assign({}, node, {children: all(h, node)})
},
mdxBlockExpression(h, node) {
return Object.assign({}, node, {
type: 'comment'
type: 'mdxBlockExpression'
})
},
jsx(h, node) {
mdxSpanExpression(h, node) {
return Object.assign({}, node, {
type: 'jsx'
type: 'mdxSpanExpression'
})

@@ -90,5 +99,3 @@ }

const hast = toHAST(tree, {
handlers,
// Enable passing of HTML nodes to HAST as raw nodes
allowDangerousHtml: true
handlers
})

@@ -95,0 +102,0 @@

const {transformSync} = require('@babel/core')
const styleToObject = require('style-to-object')
const camelCaseCSS = require('camelcase-css')
const uniq = require('lodash.uniq')
const {paramCase, toTemplateLiteral} = require('@mdx-js/util')
const {serializeTags} = require('remark-mdx/lib/serialize/mdx-element')
const serializeMdxExpression = require('remark-mdx/lib/serialize/mdx-expression')
const toH = require('hast-to-hyperscript')
const {toTemplateLiteral} = require('@mdx-js/util')
const BabelPluginApplyMdxProp = require('babel-plugin-apply-mdx-type-prop')
const BabelPluginExtractImportNames = require('babel-plugin-extract-import-names')
// From https://github.com/wooorm/property-information/blob/ca74feb1fcd40753367c75b63c893353cd7d8c70/lib/html.js
const spaceSeparatedProperties = [
'acceptCharset',
'accessKey',
'autoComplete',
'className',
'controlsList',
'headers',
'htmlFor',
'httpEquiv',
'itemProp',
'itemRef',
'itemType',
'ping',
'rel',
'sandbox'
]
function toJSX(node, parentNode = {}, options = {}) {
if (node.type === 'root') {
return serializeRoot(node, options)
}
// eslint-disable-next-line complexity
function toJSX(node, parentNode = {}, options = {}) {
if (node.type === 'element') {
return serializeElement(node, options, parentNode)
}
// Wraps text nodes inside template string, so that we don't run into escaping issues.
if (node.type === 'text') {
return serializeText(node, options, parentNode)
}
if (node.type === 'mdxBlockExpression' || node.type === 'mdxSpanExpression') {
return serializeMdxExpression(node)
}
// To do: pass `parentName` in?
if (node.type === 'mdxBlockElement' || node.type === 'mdxSpanElement') {
return serializeComponent(node, options, parentNode)
}
if (node.type === 'import' || node.type === 'export') {
return serializeEsSyntax(node)
}
}
function compile(options = {}) {
this.Compiler = function (tree) {
return toJSX(tree, {}, options)
}
}
module.exports = compile
exports = compile
exports.toJSX = toJSX
exports.default = compile
function serializeRoot(node, options) {
const {
// Default options
skipExport = false,
preserveNewlines = false,
wrapExport
} = options
let children = ''
if (node.properties != null) {
// Turn style strings into JSX-friendly style object
if (typeof node.properties.style === 'string') {
let styleObject = {}
styleToObject(node.properties.style, function (name, value) {
styleObject[camelCaseCSS(name)] = value
})
node.properties.style = styleObject
const groups = {import: [], export: [], rest: []}
for (const child of node.children) {
let kind = 'rest'
if (child.type === 'import' || child.type === 'export') {
kind = child.type
}
// Transform class property to JSX-friendly className
if (node.properties.class) {
node.properties.className = node.properties.class
delete node.properties.class
groups[kind].push(child)
}
let layout
// Find a default export, assumes there’s zero or one.
groups.export = groups.export.filter(child => {
if (child.default) {
layout = child.value
.replace(/^export\s+default\s+/, '')
.replace(/;\s*$/, '')
return false
}
// AriaProperty => aria-property
// dataProperty => data-property
const paramCaseRe = /^(aria[A-Z])|(data[A-Z])/
node.properties = Object.entries(node.properties).reduce(
(properties, [key, value]) =>
Object.assign({}, properties, {
[paramCaseRe.test(key) ? paramCase(key) : key]: value
}),
{}
return true
})
const exportNames = groups.export
.map(node =>
node.value.match(/^export\s*(var|const|let|class|function)?\s*(\w+)/)
)
}
.map(match => (Array.isArray(match) ? match[2] : null))
.filter(Boolean)
if (node.type === 'root') {
const importNodes = []
const exportNodes = []
const jsxNodes = []
let layout
for (const childNode of node.children) {
if (childNode.type === 'import') {
importNodes.push(childNode)
continue
}
const importStatements = groups.import
.map(childNode => toJSX(childNode, node))
.join('\n')
if (childNode.type === 'export') {
if (childNode.default) {
layout = childNode.value
.replace(/^export\s+default\s+/, '')
.replace(/;\s*$/, '')
continue
}
const exportStatements = groups.export
.map(childNode => toJSX(childNode, node))
.join('\n')
exportNodes.push(childNode)
continue
}
let layoutProps = 'const layoutProps = {'
jsxNodes.push(childNode)
}
if (exportNames.length !== 0) {
layoutProps += '\n ' + exportNames.join(',\n ') + '\n'
}
const exportNames = exportNodes
.map(node =>
node.value.match(/^export\s*(var|const|let|class|function)?\s*(\w+)/)
)
.map(match => (Array.isArray(match) ? match[2] : null))
.filter(Boolean)
layoutProps += '};'
const importStatements = importNodes
.map(childNode => toJSX(childNode, node))
.join('\n')
const exportStatements = exportNodes
.map(childNode => toJSX(childNode, node))
.join('\n')
const layoutProps = `const layoutProps = {
${exportNames.join(',\n')}
};`
const mdxLayout = `const MDXLayout = ${layout ? layout : '"wrapper"'}`
const mdxLayout = `const MDXLayout = ${layout ? layout : '"wrapper"'}`
const fn = `function MDXContent({ components, ...props }) {
return (
<MDXLayout
{...layoutProps}
{...props}
components={components}>
${jsxNodes.map(childNode => toJSX(childNode, node)).join('')}
</MDXLayout>
)
const doc = groups.rest
.map(childNode => toJSX(childNode, node, options))
.join('')
.replace(/^\n+|\n+$/, '')
const fn = `function MDXContent({ components, ...props }) {
return (
<MDXLayout {...layoutProps} {...props} components={components}>
${doc}
</MDXLayout>
)
};
MDXContent.isMDXComponent = true`
// Check JSX nodes against imports
const babelPluginExtractImportNamesInstance = new BabelPluginExtractImportNames()
transformSync(importStatements, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginExtractImportNamesInstance.plugin
]
})
const importNames = babelPluginExtractImportNamesInstance.state.names
// Check JSX nodes against imports
const babelPluginExtractImportNamesInstance = new BabelPluginExtractImportNames()
transformSync(importStatements, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginExtractImportNamesInstance.plugin
]
})
const importNames = babelPluginExtractImportNamesInstance.state.names
const babelPluginApplyMdxPropInstance = new BabelPluginApplyMdxProp()
const babelPluginApplyMdxPropToExportsInstance = new BabelPluginApplyMdxProp()
const babelPluginApplyMdxPropInstance = new BabelPluginApplyMdxProp()
const babelPluginApplyMdxPropToExportsInstance = new BabelPluginApplyMdxProp()
const fnPostMdxTypeProp = transformSync(fn, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginApplyMdxPropInstance.plugin
]
}).code
const fnPostMdxTypeProp = transformSync(fn, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginApplyMdxPropInstance.plugin
]
}).code
const exportStatementsPostMdxTypeProps = transformSync(exportStatements, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginApplyMdxPropToExportsInstance.plugin
]
}).code
const allJsxNames = [
...babelPluginApplyMdxPropInstance.state.names,
...babelPluginApplyMdxPropToExportsInstance.state.names
const exportStatementsPostMdxTypeProps = transformSync(exportStatements, {
configFile: false,
babelrc: false,
plugins: [
require('@babel/plugin-syntax-jsx'),
require('@babel/plugin-syntax-object-rest-spread'),
babelPluginApplyMdxPropToExportsInstance.plugin
]
const jsxNames = allJsxNames.filter(name => name !== 'MDXLayout')
}).code
const importExportNames = importNames.concat(exportNames)
const fakedModulesForGlobalScope =
`const makeShortcode = name => function MDXDefaultShortcode(props) {
const allJsxNames = [
...babelPluginApplyMdxPropInstance.state.names,
...babelPluginApplyMdxPropToExportsInstance.state.names
]
const jsxNames = allJsxNames.filter(name => name !== 'MDXLayout')
const importExportNames = importNames.concat(exportNames)
const fakedModulesForGlobalScope =
`const makeShortcode = name => function MDXDefaultShortcode(props) {
console.warn("Component " + name + " was not imported, exported, or provided by MDXProvider as global scope")

@@ -170,8 +170,8 @@ return <div {...props}/>

` +
uniq(jsxNames)
.filter(name => !importExportNames.includes(name))
.map(name => `const ${name} = makeShortcode("${name}");`)
.join('\n')
uniq(jsxNames)
.filter(name => !importExportNames.includes(name))
.map(name => `const ${name} = makeShortcode("${name}");`)
.join('\n')
const moduleBase = `${importStatements}
const moduleBase = `${importStatements}
${exportStatementsPostMdxTypeProps}

@@ -182,82 +182,93 @@ ${fakedModulesForGlobalScope}

if (skipExport) {
return `${moduleBase}
if (skipExport) {
return `${moduleBase}
${fnPostMdxTypeProp}`
}
}
if (wrapExport) {
return `${moduleBase}
if (wrapExport) {
return `${moduleBase}
${fnPostMdxTypeProp}
export default ${wrapExport}(MDXContent)`
}
}
return `${moduleBase}
return `${moduleBase}
export default ${fnPostMdxTypeProp}`
}
}
// Recursively walk through children
if (node.children) {
children = node.children
.map(childNode => {
const childOptions = Object.assign({}, options, {
// Tell all children inside <pre> tags to preserve newlines as text nodes
preserveNewlines: preserveNewlines || node.tagName === 'pre'
})
return toJSX(childNode, node, childOptions)
})
.join('')
}
function serializeElement(node, options, parentNode) {
const parentName = parentNode.tagName
const {type, props} = toH(
fakeReactCreateElement,
Object.assign({}, node, {children: []}),
{prefix: false}
)
const content = serializeChildren(node, options)
if (node.type === 'element') {
let props = ''
delete props.key
const data = parentName ? {...props, parentName} : props
if (node.properties) {
spaceSeparatedProperties.forEach(prop => {
if (Array.isArray(node.properties[prop])) {
node.properties[prop] = node.properties[prop].join(' ')
}
})
const spread =
Object.keys(data).length === 0 ? null : ' {...' + JSON.stringify(data) + '}'
if (Object.keys(node.properties).length > 0) {
props = JSON.stringify(node.properties)
}
}
return (
'<' +
type +
(spread ? ' ' + spread : '') +
(content ? '>' + content + '</' + type + '>' : '/>')
)
}
return `<${node.tagName}${
parentNode.tagName ? ` parentName="${parentNode.tagName}"` : ''
}${props ? ` {...${props}}` : ''}>${children}</${node.tagName}>`
function serializeComponent(node, options) {
let content = serializeChildren(node, options)
const tags = serializeTags(
Object.assign({}, node, {children: content ? ['!'] : []})
)
if (node.type === 'mdxBlockElement' && content) {
content = '\n' + content + '\n'
}
// Wraps text nodes inside template string, so that we don't run into escaping issues.
if (node.type === 'text') {
// Don't wrap newlines unless specifically instructed to by the flag,
// to avoid issues like React warnings caused by text nodes in tables.
const shouldPreserveNewlines =
preserveNewlines || parentNode.tagName === 'p'
return tags.open + content + (tags.close || '')
}
if (node.value === '\n' && !shouldPreserveNewlines) {
return node.value
}
function serializeText(node, options, parentNode) {
const preserveNewlines = options.preserveNewlines
// Don't wrap newlines unless specifically instructed to by the flag,
// to avoid issues like React warnings caused by text nodes in tables.
const shouldPreserveNewlines = preserveNewlines || parentNode.tagName === 'p'
return toTemplateLiteral(node.value)
if (node.value === '\n' && !shouldPreserveNewlines) {
return node.value
}
if (node.type === 'comment') {
return `{/*${node.value}*/}`
}
return toTemplateLiteral(node.value)
}
if (node.type === 'import' || node.type === 'export' || node.type === 'jsx') {
return node.value
}
function serializeEsSyntax(node) {
return node.value
}
function compile(options = {}) {
this.Compiler = function (tree) {
return toJSX(tree, {}, options)
function serializeChildren(node, options) {
const children = node.children || []
const childOptions = Object.assign({}, options, {
// Tell all children inside <pre> tags to preserve newlines as text nodes
preserveNewlines: options.preserveNewlines || node.tagName === 'pre'
})
return children
.map(childNode => {
return toJSX(childNode, node, childOptions)
})
.join('\n')
}
// We only do this for the props, so we’re ignoring children.
function fakeReactCreateElement(name, props) {
return {
type: name,
props: props,
// Needed for `toH` to think this is React.
key: null,
_owner: null
}
}
module.exports = compile
exports = compile
exports.toJSX = toJSX
exports.default = compile
{
"name": "@mdx-js/mdx",
"version": "1.6.3",
"version": "2.0.0-next.0",
"description": "Parse MDX and transpile to JSX",

@@ -23,3 +23,2 @@ "repository": "mdx-js/mdx",

"index.js",
"md-ast-to-mdx-ast.js",
"mdx-ast-to-mdx-hast.js",

@@ -41,7 +40,8 @@ "mdx-hast-to-jsx.js",

"@babel/plugin-syntax-object-rest-spread": "7.8.3",
"@mdx-js/util": "^1.6.3",
"babel-plugin-apply-mdx-type-prop": "^1.6.3",
"babel-plugin-extract-import-names": "^1.6.3",
"@mdx-js/util": "^2.0.0-next.0",
"babel-plugin-apply-mdx-type-prop": "^2.0.0-next.0",
"babel-plugin-extract-import-names": "^2.0.0-next.0",
"camelcase-css": "2.0.1",
"detab": "2.0.3",
"hast-to-hyperscript": "8.1.0",
"hast-util-raw": "5.0.2",

@@ -51,6 +51,6 @@ "lodash.uniq": "4.5.0",

"remark-footnotes": "1.0.0",
"remark-mdx": "^1.6.3",
"remark-parse": "8.0.2",
"remark-mdx": "^2.0.0-next.0",
"remark-mdxjs": "^2.0.0-next.0",
"remark-parse": "8.0.1",
"remark-squeeze-paragraphs": "4.0.0",
"style-to-object": "0.3.0",
"unified": "9.0.0",

@@ -60,3 +60,3 @@ "unist-builder": "2.0.3",

},
"gitHead": "9d71d64e21889087f4d437beaf441d1878b44789"
"gitHead": "08c809a5cc06307b816e8d99dc2e32304c04dff2"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc