diff --git a/packages/babel-plugin-apply-mdx-type-props/index.js b/packages/babel-plugin-apply-mdx-type-props/index.js index ab549dd48..c34939a04 100644 --- a/packages/babel-plugin-apply-mdx-type-props/index.js +++ b/packages/babel-plugin-apply-mdx-type-props/index.js @@ -16,6 +16,27 @@ class BabelPluginApplyMdxTypeProp { JSXOpeningElement(path) { const jsxName = path.node.name.name + let parentPath = path.parentPath.parentPath + let parentName + + while (parentPath) { + if (parentPath.node.type === 'JSXElement') { + parentName = parentPath.node.openingElement.name.name + break + } + + parentPath = parentPath.parentPath + } + + if (typeof parentName === 'string' && parentName !== 'MDXLayout') { + path.node.attributes.push( + t.jSXAttribute( + t.jSXIdentifier(`parentName`), + t.stringLiteral(parentName) + ) + ) + } + if (startsWithCapitalLetter(jsxName)) { names.push(jsxName) diff --git a/packages/babel-plugin-apply-mdx-type-props/test/index.test.js b/packages/babel-plugin-apply-mdx-type-props/test/index.test.js index 97ff81498..9c6202b6b 100644 --- a/packages/babel-plugin-apply-mdx-type-props/test/index.test.js +++ b/packages/babel-plugin-apply-mdx-type-props/test/index.test.js @@ -19,7 +19,7 @@ const transform = value => { describe('babel-plugin-add-mdx-type-prop', () => { test('should add `mdxType` to components', () => { expect(transform('var d =
').code).toEqual( - 'var d =
;' + 'var d =
;' ) }) diff --git a/packages/mdx/index.js b/packages/mdx/index.js index 668c57eaf..31b3b06f8 100644 --- a/packages/mdx/index.js +++ b/packages/mdx/index.js @@ -2,6 +2,7 @@ const unified = require('unified') const remarkParse = require('remark-parse') const remarkMdx = require('remark-mdx') const squeeze = require('remark-squeeze-paragraphs') +const minifyWhitespace = require('rehype-minify-whitespace') const mdxAstToMdxHast = require('./mdx-ast-to-mdx-hast') const mdxHastToJsx = require('./mdx-hast-to-jsx') @@ -19,6 +20,7 @@ function createMdxAstCompiler(options = {}) { function createCompiler(options = {}) { return createMdxAstCompiler(options) .use(options.rehypePlugins) + .use(minifyWhitespace, {newlines: true}) .use(mdxHastToJsx, options) } diff --git a/packages/mdx/mdx-hast-to-jsx.js b/packages/mdx/mdx-hast-to-jsx.js index 48327af3d..6387e400a 100644 --- a/packages/mdx/mdx-hast-to-jsx.js +++ b/packages/mdx/mdx-hast-to-jsx.js @@ -1,255 +1,114 @@ -const {transformSync} = require('@babel/core') +const {transformFromAstSync} = require('@babel/core') +const generate = require('@babel/generator').default const uniq = require('lodash.uniq') -const encode = require('stringify-entities/light') -const toH = require('hast-to-hyperscript') -const recast = require('recast') +const toEstree = require('hast-util-to-estree') +const estreeToBabel = require('estree-to-babel') const BabelPluginApplyMdxProp = require('babel-plugin-apply-mdx-type-prop') const BabelPluginExtractImportNames = require('babel-plugin-extract-import-names') const BabelPluginExtractExportNames = require('babel-plugin-extract-export-names') -// To do: `recast` might be heavy (have to check), and `astring` might be a good -// alternative. -// However, `astring` doesn’t support JSX. -// When we start compiling JSX away, `astring` might be a good fit though. - -function toJSX(node, parentNode = {}, options = {}) { - if (node.type === 'root') { - return serializeRoot(node, 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 === 'mdxFlowExpression' || node.type === 'mdxTextExpression') { - return serializeMdxExpression(node) - } - - // To do: pass `parentName` in? - if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') { - return serializeComponent(node, options, parentNode) - } -} - -function serializeRoot(node, options) { +function serializeEstree(estree, options) { const { // Default options skipExport = false, wrapExport } = options - const groups = {mdxjsEsm: [], rest: []} - - node.children.forEach(child => { - groups[child.type === 'mdxjsEsm' ? child.type : 'rest'].push(child) - }) - - // Find a default export, assumes there’s zero or one. - const importStatements = [] - const exportStatements = [] let layout + let children = [] + + // Find the `export default`, the JSX expression, and leave the rest + // (import/exports) as they are. + estree.body = estree.body.filter(child => { + if (child.type === 'ExportDefaultDeclaration') { + layout = child.declaration + return false + } - groups.mdxjsEsm.forEach(child => { - child.data.estree.body.forEach(eschild => { - if (eschild.type === 'ImportDeclaration') { - importStatements.push(recast.prettyPrint(eschild).code) - } else if (eschild.type === 'ExportDefaultDeclaration') { - layout = recast.prettyPrint(eschild.declaration).code - } else { - exportStatements.push(recast.prettyPrint(eschild).code) - } - }) + if ( + child.type === 'ExpressionStatement' && + (child.expression.type === 'JSXFragment' || + child.expression.type === 'JSXElement') + ) { + children = + child.expression.type === 'JSXFragment' + ? child.expression.children + : [child.expression] + return false + } + + return true }) - const doc = groups.rest - .map(childNode => toJSX(childNode, node, options)) - .join('') - .replace(/^\n+|\n+$/, '') + estree.body = [ + ...estree.body, + ...createMdxLayout(layout), + ...createMdxContent(children) + ] - const fn = `function MDXContent({ components, ...props }) { -return ( - -${doc} - -) -}; -MDXContent.isMDXComponent = true` + // Now, transform the whole with Babel. + const babelTree = estreeToBabel(estree) - // Check JSX nodes against imports + // Get all the identifiers that are imported or exported (as those might be + // component names). const babelPluginExtractImportNamesInstance = new BabelPluginExtractImportNames() const babelPluginExtractExportNamesInstance = new BabelPluginExtractExportNames() - const importsAndExports = [] - .concat(importStatements, exportStatements) - .join('\n') - - transformSync(importsAndExports, { - configFile: false, - babelrc: false, - plugins: [ - require('@babel/plugin-syntax-jsx'), - require('@babel/plugin-syntax-object-rest-spread'), - babelPluginExtractImportNamesInstance.plugin, - babelPluginExtractExportNamesInstance.plugin - ] - }) - - const importNames = babelPluginExtractImportNamesInstance.state.names - const exportNames = babelPluginExtractExportNamesInstance.state.names - - // Add `mdxType` props. + // Get all used JSX identifiers (`mdxType` props). const babelPluginApplyMdxPropInstance = new BabelPluginApplyMdxProp() - const babelPluginApplyMdxPropToExportsInstance = new BabelPluginApplyMdxProp() - const fnPostMdxTypeProp = transformSync(fn, { + // Mutate the Babel AST. + transformFromAstSync(babelTree, '', { + ast: false, + code: false, + cloneInputAst: false, configFile: false, babelrc: false, plugins: [ - require('@babel/plugin-syntax-jsx'), - require('@babel/plugin-syntax-object-rest-spread'), + babelPluginExtractImportNamesInstance.plugin, + babelPluginExtractExportNamesInstance.plugin, babelPluginApplyMdxPropInstance.plugin ] - }).code - - const exportStatementsPostMdxTypeProps = transformSync( - exportStatements.join('\n'), - { - 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 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") - return
-}; -` + - uniq(jsxNames) - .filter(name => !importExportNames.includes(name)) - .map(name => `const ${name} = makeShortcode("${name}");`) - .join('\n') - - const moduleBase = `${importStatements} -${exportStatementsPostMdxTypeProps} -${fakedModulesForGlobalScope} -const MDXLayout = ${layout || '"wrapper"'}` - - if (skipExport) { - return `${moduleBase} -${fnPostMdxTypeProp}` - } - - if (wrapExport) { - return `${moduleBase} -${fnPostMdxTypeProp} -export default ${wrapExport}(MDXContent)` - } - - return `${moduleBase} -export default ${fnPostMdxTypeProp}` -} + }) -function serializeElement(node, options, parentNode) { - const parentName = parentNode.tagName - const {type, props} = toH( - fakeReactCreateElement, - Object.assign({}, node, {children: []}), - {prefix: false} + const importExportNames = babelPluginExtractImportNamesInstance.state.names.concat( + babelPluginExtractExportNamesInstance.state.names ) - const content = serializeChildren(node, options) - - delete props.key - const data = parentName ? {...props, parentName} : props - - const spread = - Object.keys(data).length === 0 ? null : ' {...' + JSON.stringify(data) + '}' - - return ( - '<' + - type + - (spread ? ' ' + spread : '') + - (content ? '>' + content + '' : '/>') + const jsxNames = babelPluginApplyMdxPropInstance.state.names.filter( + name => name !== 'MDXLayout' ) -} - -function serializeComponent(node, options) { - const tags = serializeTags(node) - let content = serializeChildren(node, options) - - if (node.type === 'mdxJsxFlowElement' && content) { - content = '\n' + content + '\n' - } - - return tags.open + content + (tags.close || '') -} - -function serializeText(node, options, parentNode) { - // Don't wrap newlines unless specifically instructed to by the flag, - // to avoid issues like React warnings caused by text nodes in tables. - const preserveNewlines = - options.preserveNewlines || parentNode.tagName === 'p' - if (node.value === '\n' && !preserveNewlines) { - return node.value - } + const shortcodes = createMakeShortcodeHelper( + uniq(jsxNames).filter(name => !importExportNames.includes(name)) + ) - return toTemplateLiteral(node.value) -} + const exports = [] -function serializeChildren(node, options) { - const children = node.children || [] - const childOptions = Object.assign({}, options, { - // Tell all children inside
 tags to preserve newlines as text nodes
-    preserveNewlines: options.preserveNewlines || node.tagName === 'pre'
-  })
+  if (!skipExport) {
+    let declaration = {type: 'Identifier', name: 'MDXContent'}
 
-  return children.map(child => toJSX(child, node, childOptions)).join('\n')
-}
+    if (wrapExport) {
+      declaration = {
+        type: 'CallExpression',
+        callee: {type: 'Identifier', name: wrapExport},
+        arguments: [declaration]
+      }
+    }
 
-// 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
+    exports.push({type: 'ExportDefaultDeclaration', declaration: declaration})
   }
-}
 
-function toTemplateLiteral(value) {
-  const escaped = value
-    .replace(/\\(?!\$)/g, '\\\\') // Escape all "\" to avoid unwanted escaping in text nodes
-    // and ignore "\$" since it's already escaped and is common
-    // with prettier https://github.com/mdx-js/mdx/issues/606
-    .replace(/`/g, '\\`') // Escape "`"" since
-    .replace(/(\\\$)/g, '\\$1') // Escape \$ so render it as it is
-    .replace(/(\\\$)(\{)/g, '\\$1\\$2') // Escape \${} so render it as it is
-    .replace(/\$\{/g, '\\${') // Escape ${} in text so that it doesn't eval
+  babelTree.program.body = [
+    ...shortcodes,
+    ...babelTree.program.body,
+    ...exports
+  ]
 
-  return '{`' + escaped + '`}'
+  return generate(babelTree).code
 }
 
 function compile(options = {}) {
   function compiler(tree) {
-    return toJSX(tree, undefined, options)
+    return serializeEstree(toEstree(tree), options)
   }
 
   this.Compiler = compiler
@@ -257,92 +116,197 @@ function compile(options = {}) {
 
 module.exports = compile
 compile.default = compile
-compile.toJSX = toJSX
-
-// To do: this is all extracted (and simplified) from `mdast-util-mdx-jsx` for
-// now.
-// We can remove it when we drop JSX!
-
-const eol = /\r?\n|\r/g
-
-function serializeTags(node) {
-  const selfClosing = node.name && (!node.children || !node.children.length)
-  const attributes = []
-  let index = -1
-  let attribute
-  let result
-
-  // None.
-  if (node.attributes && node.attributes.length) {
-    if (!node.name) {
-      throw new Error('Cannot serialize fragment w/ attributes')
-    }
-
-    while (++index < node.attributes.length) {
-      attribute = node.attributes[index]
 
-      if (attribute.type === 'mdxJsxExpressionAttribute') {
-        result = '{' + (attribute.value || '') + '}'
-      } else {
-        if (!attribute.name) {
-          throw new Error('Cannot serialize attribute w/o name')
+function createMdxContent(children) {
+  return [
+    {
+      type: 'FunctionDeclaration',
+      id: {type: 'Identifier', name: 'MDXContent'},
+      expression: false,
+      generator: false,
+      async: false,
+      params: [
+        {
+          type: 'ObjectPattern',
+          properties: [
+            {
+              type: 'Property',
+              method: false,
+              shorthand: true,
+              computed: false,
+              key: {type: 'Identifier', name: 'components'},
+              kind: 'init',
+              value: {type: 'Identifier', name: 'components'}
+            },
+            {type: 'RestElement', argument: {type: 'Identifier', name: 'props'}}
+          ]
         }
-
-        result =
-          attribute.name +
-          (attribute.value == null
-            ? ''
-            : '=' +
-              (typeof attribute.value === 'object'
-                ? '{' + (attribute.value.value || '') + '}'
-                : '"' + encode(attribute.value, {subset: ['"']}) + '"'))
+      ],
+      body: {
+        type: 'BlockStatement',
+        body: [
+          {
+            type: 'ReturnStatement',
+            argument: {
+              type: 'JSXElement',
+              openingElement: {
+                type: 'JSXOpeningElement',
+                attributes: [
+                  {
+                    type: 'JSXAttribute',
+                    name: {type: 'JSXIdentifier', name: 'components'},
+                    value: {
+                      type: 'JSXExpressionContainer',
+                      expression: {type: 'Identifier', name: 'components'}
+                    }
+                  },
+                  {
+                    type: 'JSXSpreadAttribute',
+                    argument: {type: 'Identifier', name: 'props'}
+                  }
+                ],
+                name: {type: 'JSXIdentifier', name: 'MDXLayout'},
+                selfClosing: false
+              },
+              closingElement: {
+                type: 'JSXClosingElement',
+                name: {type: 'JSXIdentifier', name: 'MDXLayout'}
+              },
+              children: children
+            }
+          }
+        ]
+      }
+    },
+    {
+      type: 'ExpressionStatement',
+      expression: {
+        type: 'AssignmentExpression',
+        operator: '=',
+        left: {
+          type: 'MemberExpression',
+          object: {type: 'Identifier', name: 'MDXContent'},
+          property: {type: 'Identifier', name: 'isMDXComponent'},
+          computed: false,
+          optional: false
+        },
+        right: {type: 'Literal', value: true, raw: 'true'}
       }
-
-      attributes.push(result)
     }
-  }
-
-  return {
-    open:
-      '<' +
-      (node.name || '') +
-      (node.type === 'mdxJsxFlowElement' && attributes.length > 1
-        ? // Flow w/ multiple attributes.
-          '\n' + indent(attributes.join('\n')) + '\n'
-        : attributes.length // Text or flow w/ a single attribute.
-        ? ' ' + dedentStart(indent(attributes.join(' ')))
-        : '') +
-      (selfClosing ? '/' : '') +
-      '>',
-    close: selfClosing ? '' : ''
-  }
-}
-
-function serializeMdxExpression(node) {
-  const value = node.value || ''
-  return '{' + (node.type === 'mdxFlowExpression' ? indent(value) : value) + '}'
+  ]
 }
 
-function dedentStart(value) {
-  return value.replace(/^ +/, '')
+function createMdxLayout(declaration) {
+  return [
+    {
+      type: 'VariableDeclaration',
+      declarations: [
+        {
+          type: 'VariableDeclarator',
+          id: {type: 'Identifier', name: 'MDXLayout'},
+          init: declaration || {
+            type: 'Literal',
+            value: 'wrapper',
+            raw: '"wrapper"'
+          }
+        }
+      ],
+      kind: 'const'
+    }
+  ]
 }
 
-function indent(value) {
-  const result = []
-  let start = 0
-  let match
-
-  while ((match = eol.exec(value))) {
-    one(value.slice(start, match.index))
-    result.push(match[0])
-    start = match.index + match[0].length
+// Note: this creates a Babel AST, not an estree.
+function createMakeShortcodeHelper(names) {
+  const func = {
+    type: 'VariableDeclaration',
+    declarations: [
+      {
+        type: 'VariableDeclarator',
+        id: {type: 'Identifier', name: 'makeShortcode'},
+        init: {
+          type: 'ArrowFunctionExpression',
+          id: null,
+          expression: true,
+          generator: false,
+          async: false,
+          params: [{type: 'Identifier', name: 'name'}],
+          body: {
+            type: 'ArrowFunctionExpression',
+            id: null,
+            expression: false,
+            generator: false,
+            async: false,
+            params: [{type: 'Identifier', name: 'props'}],
+            body: {
+              type: 'BlockStatement',
+              body: [
+                {
+                  type: 'ExpressionStatement',
+                  expression: {
+                    type: 'CallExpression',
+                    callee: {
+                      type: 'MemberExpression',
+                      object: {type: 'Identifier', name: 'console'},
+                      property: {type: 'Identifier', name: 'warn'},
+                      computed: false,
+                      optional: false
+                    },
+                    arguments: [
+                      {
+                        // Note: Babel!
+                        type: 'StringLiteral',
+                        value:
+                          'Component %s was not imported, exported, or provided by MDXProvider as global scope'
+                      },
+                      {type: 'Identifier', name: 'name'}
+                    ]
+                  }
+                },
+                {
+                  type: 'ReturnStatement',
+                  argument: {
+                    type: 'JSXElement',
+                    openingElement: {
+                      type: 'JSXOpeningElement',
+                      attributes: [
+                        {
+                          type: 'JSXSpreadAttribute',
+                          argument: {type: 'Identifier', name: 'props'}
+                        }
+                      ],
+                      name: {type: 'JSXIdentifier', name: 'div'},
+                      selfClosing: true
+                    },
+                    closingElement: null,
+                    children: []
+                  }
+                }
+              ]
+            }
+          }
+        }
+      }
+    ],
+    kind: 'const'
   }
 
-  one(value.slice(start))
-
-  return result.join('')
+  const shortcodes = names.map(name => ({
+    type: 'VariableDeclaration',
+    declarations: [
+      {
+        type: 'VariableDeclarator',
+        id: {type: 'Identifier', name: String(name)},
+        init: {
+          type: 'CallExpression',
+          callee: {type: 'Identifier', name: 'makeShortcode'},
+          // Note: Babel!
+          arguments: [{type: 'StringLiteral', value: String(name)}]
+        }
+      }
+    ],
+    kind: 'const'
+  }))
 
-  function one(slice) {
-    result.push((slice ? '  ' : '') + slice)
-  }
+  return [func, ...shortcodes]
 }
diff --git a/packages/mdx/package.json b/packages/mdx/package.json
index de527f7c2..df81fcf1e 100644
--- a/packages/mdx/package.json
+++ b/packages/mdx/package.json
@@ -42,23 +42,22 @@
     "test": "yarn test-coverage && yarn test-types"
   },
   "dependencies": {
-    "@babel/core": "7.10.5",
-    "@babel/plugin-syntax-jsx": "7.10.4",
-    "@babel/plugin-syntax-object-rest-spread": "7.8.3",
+    "@babel/core": "^7.12.10",
+    "@babel/generator": "^7.12.10",
     "@mdx-js/util": "2.0.0-next.1",
     "babel-plugin-apply-mdx-type-prop": "^2.0.0-next.8",
     "babel-plugin-extract-export-names": "^2.0.0-next.8",
     "babel-plugin-extract-import-names": "^2.0.0-next.8",
     "detab": "2.0.3",
-    "hast-to-hyperscript": "9.0.0",
+    "estree-to-babel": "^3.0.0",
+    "hast-util-to-estree": "^1.0.3",
     "lodash.uniq": "4.5.0",
     "mdast-util-to-hast": "10.0.1",
-    "recast": "^0.20.4",
+    "rehype-minify-whitespace": "^4.0.0",
     "remark-mdx": "^2.0.0-next.8",
-    "remark-parse": "9.0.0",
-    "remark-squeeze-paragraphs": "4.0.0",
-    "stringify-entities": "^3.1.0",
-    "unified": "9.0.0",
+    "remark-parse": "^9.0.0",
+    "remark-squeeze-paragraphs": "^4.0.0",
+    "unified": "^9.2.0",
     "unist-builder": "2.0.3"
   },
   "devDependencies": {
diff --git a/packages/mdx/test/index.test.js b/packages/mdx/test/index.test.js
index 3a37c5900..05ca9b928 100644
--- a/packages/mdx/test/index.test.js
+++ b/packages/mdx/test/index.test.js
@@ -33,7 +33,7 @@ describe('@mdx-js/mdx', () => {
   it('should generate JSX', async () => {
     const result = await mdx('Hello World')
 
-    expect(result).toMatch(/

\{`Hello World`\}<\/p>/) + expect(result).toMatch(/

\{"Hello World"\}<\/p>/) }) it('should generate runnable JSX', async () => { @@ -304,6 +304,32 @@ describe('@mdx-js/mdx', () => { ) }) + it('should support an empty document', async () => { + const Content = await run('') + + expect(renderToStaticMarkup()).toEqual( + renderToStaticMarkup(<>) + ) + }) + + it('should support an ignored node instead of a `root`', async () => { + const plugin = () => () => ({type: 'doctype', name: 'html'}) + const Content = await run('', {rehypePlugins: [plugin]}) + + expect(renderToStaticMarkup()).toEqual( + renderToStaticMarkup(<>) + ) + }) + + it('should support an element instead of a `root`', async () => { + const plugin = () => () => ({type: 'element', tagName: 'x', children: []}) + const Content = await run('', {rehypePlugins: [plugin]}) + + expect(renderToStaticMarkup()).toEqual( + renderToStaticMarkup() + ) + }) + it('should support imports', async () => { expect.assertions(2) @@ -526,7 +552,8 @@ describe('@mdx-js/mdx', () => { ) expect(console.warn).toHaveBeenCalledWith( - 'Component Y was not imported, exported, or provided by MDXProvider as global scope' + 'Component %s was not imported, exported, or provided by MDXProvider as global scope', + 'Y' ) console.warn = warn @@ -542,7 +569,7 @@ describe('@mdx-js/mdx', () => { ) }) - it('should ignore unknown nodes in mdxhast', async () => { + it('should crash on unknown nodes in mdxhast', async () => { const plugin = () => tree => { // A leaf. tree.children.push({type: 'unknown', value: 'y'}) @@ -554,28 +581,9 @@ describe('@mdx-js/mdx', () => { }) } - const Content = await run('x', {rehypePlugins: [plugin]}) - - expect(renderToStaticMarkup()).toEqual( - renderToStaticMarkup(

x

) - ) - }) - - it('should support `element` nodes w/o `children` in mdxhast', async () => { - const plugin = () => tree => { - tree.children.push({type: 'element', tagName: 'y', properties: {}}) - } - - const Content = await run('x', {rehypePlugins: [plugin]}) - - expect(renderToStaticMarkup()).toEqual( - renderToStaticMarkup( - <> -

x

- - - ) - ) + expect(() => { + mdx.sync('x', {rehypePlugins: [plugin]}) + }).toThrow(/Cannot handle unknown node `unknown`/) }) it('should support `element` nodes w/o `properties` in mdxhast', async () => { @@ -606,7 +614,7 @@ describe('@mdx-js/mdx', () => { expect(resultDefault).toEqual(resultFalse) expect(resultTrue).toMatch(/\nfunction MDXContent/) - expect(resultFalse).toMatch(/export default function MDXContent/) + expect(resultFalse).toMatch(/export default MDXContent/) }) it('should support `wrapExport` to wrap the exported value', async () => { @@ -616,7 +624,7 @@ describe('@mdx-js/mdx', () => { expect(resultDefault).toEqual(resultNull) expect(resultValue).toMatch(/export default y\(MDXContent\)/) - expect(resultNull).toMatch(/export default function MDXContent/) + expect(resultNull).toMatch(/export default MDXContent/) }) it('should expose an `isMDXComponent` field on the component', async () => { @@ -658,24 +666,24 @@ describe('@mdx-js/mdx', () => { describe('default', () => { it('should be async', async () => { - expect(mdx('x')).resolves.toMatch(/

{`x`}<\/p>/) + expect(mdx('x')).resolves.toMatch(/

{"x"}<\/p>/) }) it('should support `remarkPlugins`', async () => { expect(mdx('$x$', {remarkPlugins: [math]})).resolves.toMatch( - /"className": "math math-inline",/ + /className="math math-inline"/ ) }) }) describe('sync', () => { it('should be sync', () => { - expect(mdx.sync('x')).toMatch(/

{`x`}<\/p>/) + expect(mdx.sync('x')).toMatch(/

{"x"}<\/p>/) }) it('should support `remarkPlugins`', () => { expect(mdx.sync('$x$', {remarkPlugins: [math]})).toMatch( - /"className": "math math-inline",/ + /className="math math-inline"/ ) }) }) @@ -719,7 +727,7 @@ describe('createMdxAstCompiler', () => { describe('createCompiler', () => { it('should create a unified processor', () => { expect(String(mdx.createCompiler().processSync('x'))).toMatch( - /

{`x`}<\/p>/ + /

{"x"}<\/p>/ ) }) }) @@ -757,26 +765,13 @@ describe('mdx-hast-to-jsx', () => { const tree = { type: 'root', children: [ - { - type: 'element', - tagName: 'x', - children: [{type: 'mdxTextExpression', value: '1 + 1'}] - } + {type: 'element', tagName: 'x', children: [{type: 'text', value: 'a'}]} ] } const doc = unified().use(toJsx).stringify(tree) - expect(doc).toMatch(/export default function MDXContent/) - expect(doc).toMatch(/\{1 \+ 1}<\/x>/) - }) -}) - -describe('mdx-hast-to-jsx.toJSX', () => { - it('should be a function that serializes mdxhast nodes', () => { - expect(toJsx.toJSX({type: 'element', tagName: 'x'})).toEqual('') - expect(toJsx.toJSX({type: 'mdxTextExpression', value: '1 + 1'})).toEqual( - '{1 + 1}' - ) + expect(doc).toMatch(/export default MDXContent/) + expect(doc).toMatch(/\{"a"}<\/x>/) }) }) diff --git a/packages/preact/test/test.js b/packages/preact/test/test.js index fd848635c..96291ee28 100644 --- a/packages/preact/test/test.js +++ b/packages/preact/test/test.js @@ -58,7 +58,8 @@ describe('@mdx-js/preact', () => { expect(render()).toEqual('

') expect(console.warn).toHaveBeenCalledWith( - 'Component Component was not imported, exported, or provided by MDXProvider as global scope' + 'Component %s was not imported, exported, or provided by MDXProvider as global scope', + 'Component' ) console.warn = warn diff --git a/packages/react/test/test.js b/packages/react/test/test.js index e461049bc..012d31bb9 100644 --- a/packages/react/test/test.js +++ b/packages/react/test/test.js @@ -58,7 +58,8 @@ describe('@mdx-js/react', () => { expect(renderToString()).toEqual('
') expect(console.warn).toHaveBeenCalledWith( - 'Component Component was not imported, exported, or provided by MDXProvider as global scope' + 'Component %s was not imported, exported, or provided by MDXProvider as global scope', + 'Component' ) console.warn = warn diff --git a/packages/vue-loader/package.json b/packages/vue-loader/package.json index 0cce6e86a..f67f46734 100644 --- a/packages/vue-loader/package.json +++ b/packages/vue-loader/package.json @@ -48,6 +48,7 @@ }, "devDependencies": { "@vue/test-utils": "^1.0.0", + "babel-helper-vue-jsx-merge-props": "^2.0.0", "babel-plugin-transform-vue-jsx": "^4.0.0", "memory-fs": "^0.5.0", "rehype-autolink-headings": "^5.0.0", diff --git a/packages/vue/package.json b/packages/vue/package.json index 8924638d6..3d1e423b7 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -34,13 +34,10 @@ }, "devDependencies": { "@vue/test-utils": "^1.1.1", - "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-helper-vue-jsx-merge-props": "^2.0.0", "microbundle": "^0.12.0" }, - "dependencies": { - "hast-to-hyperscript": "^9.0.0", - "hastscript": "^6.0.0" - }, + "dependencies": {}, "jest": { "testEnvironment": "jsdom" }, diff --git a/packages/vue/src/create-element.js b/packages/vue/src/create-element.js index 04b4f0a09..7a7c68f55 100644 --- a/packages/vue/src/create-element.js +++ b/packages/vue/src/create-element.js @@ -1,6 +1,3 @@ -import h from 'hastscript' -import toH from 'hast-to-hyperscript' - /** * MDX default components */ @@ -17,15 +14,17 @@ const defaults = { const own = {}.hasOwnProperty -export default function createMdxElement(type, props, ...children) { - let node - +export default function createMdxElement(type, props, children) { if (own.call(this.components, type)) { type = this.components[type] } else if (own.call(defaults, type)) { type = defaults[type] } + if (!children) { + children = [] + } + if (props && typeof props === 'object' && !Array.isArray(props)) { // Empty. } else { @@ -33,29 +32,17 @@ export default function createMdxElement(type, props, ...children) { props = {} } - children = children - .flatMap(d => (d == null ? [] : d)) - .map(d => - typeof d === 'number' || typeof d === 'string' - ? this.createElement('d', {}, String(d)).children[0] - : d - ) - - if (typeof type === 'string') { - node = toH( - this.createElement, - h( - type, - Object.assign({}, props, { - components: null, - mdxType: null, - parentName: null - }) - ), - {prefix: false} - ) - node.children = children - return node + children = children.map(d => + typeof d === 'number' || typeof d === 'string' + ? this.createElement('d', {}, String(d)).children[0] + : d + ) + + if (props.attrs) { + // Vue places the special MDX props in `props.attrs`, move them back into + // `props`. + const {components, mdxType, parentName, ...attrs} = props.attrs + props = {...props, components, mdxType, parentName, attrs} } // Just a render function. @@ -67,5 +54,5 @@ export default function createMdxElement(type, props, ...children) { } // Vue component. - return this.createElement(type, {props}, children) + return this.createElement(type, props, children) } diff --git a/packages/vue/test/test.js b/packages/vue/test/test.js index 641ed676f..67338b650 100644 --- a/packages/vue/test/test.js +++ b/packages/vue/test/test.js @@ -1,6 +1,7 @@ import path from 'path' import {mount} from '@vue/test-utils' import mdxTransform from '../../mdx' +import vueMergeProps from 'babel-helper-vue-jsx-merge-props' import {transformAsync as babelTransform} from '@babel/core' import {MDXProvider, mdx} from '../src' @@ -12,9 +13,7 @@ const run = async value => { const {code} = await babelTransform(doc, { configFile: false, plugins: [ - // Here we use react-jsx, which does support a pragma. - // `vue-loader` tests with `babel-plugin-transform-vue-jsx`. - '@babel/plugin-transform-react-jsx', + 'babel-plugin-transform-vue-jsx', path.resolve(__dirname, '../../babel-plugin-remove-export-keywords') ] }) @@ -22,9 +21,13 @@ const run = async value => { // …and finally run it, returning the component. // eslint-disable-next-line no-new-func return new Function( - 'unboundMdx', - `let mdx; - ${code}; + 'mdx', + '_mergeJSXProps', + `let h; + ${code.replace( + /import _mergeJSXProps from "babel-helper-vue-jsx-merge-props";/, + '' + )}; return { name: 'Mdx', @@ -39,11 +42,11 @@ const run = async value => { } }, render(createElement) { - mdx = unboundMdx.bind({ createElement, components: this.components }) - return MDXContent({ components: this.components }) + h = mdx.bind({createElement, components: this.components}) + return MDXContent({components: this.components}) } }` - )(mdx) + )(mdx, vueMergeProps) } describe('@mdx-js/vue', () => { @@ -87,13 +90,11 @@ describe('@mdx-js/vue', () => { const warn = console.warn console.warn = jest.fn() - // The literal `undefined` is because the shortcode injected by `mdx-js/mdx`, - // combined with react-jsx, yields a for Vue unexpected value: a function - // instead of props. - expect(mount(Content).html()).toEqual('
undefined
') + expect(mount(Content).html()).toEqual('
') expect(console.warn).toHaveBeenCalledWith( - 'Component Component was not imported, exported, or provided by MDXProvider as global scope' + 'Component %s was not imported, exported, or provided by MDXProvider as global scope', + 'Component' ) console.warn = warn @@ -161,7 +162,7 @@ describe('MDXProvider', () => { } }).html() ).toEqual( - '
\n

a and c.

\n
' + '
\n

a and c.

\n
' ) console.error = error diff --git a/yarn.lock b/yarn.lock index ce4923f84..5b5d3dfc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -103,28 +103,6 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== -"@babel/core@7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.5.tgz#1f15e2cca8ad9a1d78a38ddba612f5e7cdbbd330" - integrity sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.5" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.10.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.5" - "@babel/types" "^7.10.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - "@babel/core@7.11.1": version "7.11.1" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" @@ -211,7 +189,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.10.2", "@babel/core@^7.10.3", "@babel/core@^7.10.5", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.4.4", "@babel/core@^7.4.5", "@babel/core@^7.5.5", "@babel/core@^7.7.5", "@babel/core@^7.9.6": +"@babel/core@^7.1.0", "@babel/core@^7.10.2", "@babel/core@^7.10.3", "@babel/core@^7.10.5", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.4.4", "@babel/core@^7.4.5", "@babel/core@^7.5.5", "@babel/core@^7.7.5", "@babel/core@^7.9.6": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== @@ -232,7 +210,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.10.3", "@babel/generator@^7.10.5", "@babel/generator@^7.11.0", "@babel/generator@^7.12.10", "@babel/generator@^7.12.5", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.7.7", "@babel/generator@^7.9.0": +"@babel/generator@^7.10.3", "@babel/generator@^7.11.0", "@babel/generator@^7.12.10", "@babel/generator@^7.12.5", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.7.7", "@babel/generator@^7.9.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.10.tgz#2b188fc329fb8e4f762181703beffc0fe6df3460" integrity sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww== @@ -355,7 +333,7 @@ dependencies: "@babel/types" "^7.12.5" -"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.9.0": +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.9.0": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== @@ -460,7 +438,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.10.3", "@babel/parser@^7.10.5", "@babel/parser@^7.11.1", "@babel/parser@^7.12.10", "@babel/parser@^7.12.5", "@babel/parser@^7.12.7", "@babel/parser@^7.3.3", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.7.0", "@babel/parser@^7.7.7", "@babel/parser@^7.9.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.10.3", "@babel/parser@^7.11.1", "@babel/parser@^7.12.10", "@babel/parser@^7.12.5", "@babel/parser@^7.12.7", "@babel/parser@^7.3.3", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.7.0", "@babel/parser@^7.7.7", "@babel/parser@^7.9.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.10.tgz#824600d59e96aea26a5a2af5a9d812af05c3ae81" integrity sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA== @@ -1561,7 +1539,7 @@ "@babel/parser" "^7.12.7" "@babel/types" "^7.12.7" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.3", "@babel/traverse@^7.10.4", "@babel/traverse@^7.10.5", "@babel/traverse@^7.11.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.9.0": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.10.3", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.9.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a" integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg== @@ -1603,7 +1581,7 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.3", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.4", "@babel/types@^7.9.0": +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.3", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.4", "@babel/types@^7.9.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.10.tgz#7965e4a7260b26f09c56bcfcb0498af1f6d9b260" integrity sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw== @@ -4748,9 +4726,9 @@ integrity sha512-1+7CwjQ0Kasml6rHoNQUmbISwqLNNfFVBUcZl6QBremUl296ZmLrVQPqJP5pyAAWjZke5bpI1hlj+LVVuT7Jcg== "@vue/babel-plugin-jsx@^1.0.0-0": - version "1.0.0-rc.4" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.0-rc.4.tgz#02c9ba2e01dc5251fd69a89afd49e9a1963331ba" - integrity sha512-ifzYc0jfLqiQebfqzKrJGfmQFE1lIgFlE9Ive8hQMJS/GC9Y+mNtHpqmWyqljbFGsqmsxmMRNFdAUgz0HZN1rg== + version "1.0.0-rc.5" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.0-rc.5.tgz#e440be2d0775ee3828cba2c38a03b19a92174865" + integrity sha512-IUxERGiEeX9i1Vt9UtBYqOtfPYjOwEP0sFyPRI8xjkXAhJpaAIwa8JdcYakOqzIlXwhk3XD+7VFdyr/v+rLLFw== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.0.0" @@ -5063,9 +5041,9 @@ integrity sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ== "@vue/test-utils@^1.0.0", "@vue/test-utils@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.1.1.tgz#01c3e4b22ed2b85d2e276b34d32c8ac4b726e452" - integrity sha512-/32538ilZ9qSiu1gui7zfBn+IFy+zoTaQTZ1qiLfQXzZtaeAD23kJMrnqaoe2w8JzJoXuqHUl2ruuStG8rwFYQ== + version "1.1.2" + resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.1.2.tgz#fdb487448dceefeaf3d01d465f7c836a3d666dbc" + integrity sha512-utbIL7zn9c+SjhybPwh48lpWCiluFCbP1yyRNAy1fQsw/6hiNFioaWy05FoVAFIZXC5WwBf+5r4ypfM1j/nI4A== dependencies: dom-event-types "^1.0.0" lodash "^4.17.15" @@ -6083,13 +6061,6 @@ ast-types@0.13.2: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== -ast-types@0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -6423,7 +6394,7 @@ babel-helper-replace-supers@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-helper-vue-jsx-merge-props@^2.0.3: +babel-helper-vue-jsx-merge-props@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6" integrity sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg== @@ -12218,7 +12189,7 @@ esprima@^3.1.3: resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -12252,6 +12223,14 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estree-to-babel@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.0.0.tgz#1f350512341de43230c66520fa19f0ffb895fc52" + integrity sha512-yOmbku+VGwgq5TNjqJSss4NQfdiolWV8vmf3EGHvHF7zbmlVmu0RdsaF6spNFqxgrz8ccjxeC1VVjnCbiGIweg== + dependencies: + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.2.0" + estree-walker@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" @@ -14907,19 +14886,6 @@ hasha@^5.0.0, hasha@^5.2.0: is-stream "^2.0.0" type-fest "^0.8.0" -hast-to-hyperscript@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.0.tgz#768fb557765fe28749169c885056417342d71e83" - integrity sha512-NJvMYU3GlMLs7hN3CRbsNlMzusVNkYBogVWDGybsuuVQ336gFLiD+q9qtFZT2meSHzln3pNISZWTASWothMSMg== - dependencies: - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.3.0" - unist-util-is "^4.0.0" - web-namespaces "^1.0.0" - hast-to-hyperscript@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" @@ -14933,6 +14899,13 @@ hast-to-hyperscript@^9.0.0: unist-util-is "^4.0.0" web-namespaces "^1.0.0" +hast-util-embedded@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/hast-util-embedded/-/hast-util-embedded-1.0.6.tgz#ea7007323351cc43e19e1d6256b7cde66ad1aa03" + integrity sha512-JQMW+TJe0UAIXZMjCJ4Wf6ayDV9Yv3PBDPsHD4ExBpAspJ6MOcCX+nzVF+UJVv7OqPcg852WEMSHQPoRA+FVSw== + dependencies: + hast-util-is-element "^1.1.0" + hast-util-from-parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" @@ -14955,7 +14928,7 @@ hast-util-heading-rank@^1.0.0: resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-1.0.1.tgz#28dfd8b0724cfb0da48308e2a794b1d9f24fd80d" integrity sha512-P6Hq7RCky9syMevlrN90QWpqWDXCxwIVOfQR2rK6P4GpY4bqjKEuCzoWSRORZ7vz+VgRpLnXimh+mkwvVFjbyQ== -hast-util-is-element@^1.0.0: +hast-util-is-element@^1.0.0, hast-util-is-element@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425" integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ== @@ -14998,6 +14971,19 @@ hast-util-select@^1.0.1: space-separated-tokens "^1.1.0" zwitch "^1.0.0" +hast-util-to-estree@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-1.0.3.tgz#d6e849e6facf1529ecc11f1754ed439222ffa97e" + integrity sha512-ykbmmRuxCWT79HmtV817e+2x6LHnGKlDMSo4d6+ktXy/PS90+2fohuN1PhoFtp59OoldzpuCqQouyjlFLBQTcQ== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-whitespace "^1.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + style-to-object "^0.3.0" + unist-util-position "^3.1.0" + zwitch "^1.0.0" + hast-util-to-parse5@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" @@ -15018,7 +15004,7 @@ hast-util-to-text@^2.0.0: repeat-string "^1.0.0" unist-util-find-after "^3.0.0" -hast-util-whitespace@^1.0.0: +hast-util-whitespace@^1.0.0, hast-util-whitespace@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41" integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A== @@ -24130,16 +24116,6 @@ rebass@^4.0.7: dependencies: reflexbox "^4.0.6" -recast@^0.20.4: - version "0.20.4" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.4.tgz#db55983eac70c46b3fff96c8e467d65ffb4a7abc" - integrity sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ== - dependencies: - ast-types "0.14.2" - esprima "~4.0.0" - source-map "~0.6.1" - tslib "^2.0.1" - recursive-readdir@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99" @@ -24416,6 +24392,16 @@ rehype-katex@^4.0.0: unified "^9.0.0" unist-util-visit "^2.0.0" +rehype-minify-whitespace@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/rehype-minify-whitespace/-/rehype-minify-whitespace-4.0.5.tgz#5b4781786116216f6d5d7ceadf84e2489dd7b3cd" + integrity sha512-QC3Z+bZ5wbv+jGYQewpAAYhXhzuH/TVRx7z08rurBmh9AbG8Nu8oJnvs9LWj43Fd/C7UIhXoQ7Wddgt+ThWK5g== + dependencies: + hast-util-embedded "^1.0.0" + hast-util-is-element "^1.0.0" + hast-util-whitespace "^1.0.4" + unist-util-is "^4.0.0" + rehype-parse@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-7.0.1.tgz#58900f6702b56767814afc2a9efa2d42b1c90c57" @@ -25341,13 +25327,6 @@ remark-parse@8.0.3, remark-parse@^8.0.3: vfile-location "^3.0.0" xtend "^4.0.1" -remark-parse@9.0.0, remark-parse@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" - integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== - dependencies: - mdast-util-from-markdown "^0.8.0" - remark-parse@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95" @@ -25390,6 +25369,13 @@ remark-parse@^6.0.0, remark-parse@^6.0.3: vfile-location "^2.0.0" xtend "^4.0.1" +remark-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" + integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== + dependencies: + mdast-util-from-markdown "^0.8.0" + remark-preset-lint-recommended@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/remark-preset-lint-recommended/-/remark-preset-lint-recommended-4.0.1.tgz#2077b38706759277c0eb304c57453ebfa3e63207" @@ -25598,7 +25584,7 @@ remark-slug@^5.0.0: mdast-util-to-string "^1.0.0" unist-util-visit "^1.0.0" -remark-squeeze-paragraphs@4.0.0: +remark-squeeze-paragraphs@4.0.0, remark-squeeze-paragraphs@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== @@ -29110,18 +29096,6 @@ unified-ui@^0.0.3: styled-components "^4.0.2" styled-system "^3.1.11" -unified@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.0.0.tgz#12b099f97ee8b36792dbad13d278ee2f696eed1d" - integrity sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - unified@9.2.0, unified@^9.0.0, unified@^9.1.0, unified@^9.2.0: version "9.2.0" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8"