hast-util-to-estree
Advanced tools
Comparing version 1.4.0 to 2.0.0
561
index.js
@@ -1,46 +0,104 @@ | ||
'use strict' | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('hast').Parent} Parent | ||
* @typedef {import('hast').Root} Root | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').Text} Text | ||
* @typedef {import('hast').Comment} Comment | ||
* @typedef {import('hast').Properties} Properties | ||
* @typedef {import('estree-jsx').Node} EstreeNode | ||
* @typedef {import('estree-jsx').Program} EstreeProgram | ||
* @typedef {import('estree-jsx').JSXExpressionContainer} EstreeJsxExpressionContainer | ||
* @typedef {import('estree-jsx').JSXElement} EstreeJsxElement | ||
* @typedef {import('estree-jsx').JSXOpeningElement} EstreeJsxOpeningElement | ||
* @typedef {import('estree-jsx').JSXFragment} EstreeJsxFragment | ||
* @typedef {import('estree-jsx').JSXAttribute} EstreeJsxAttribute | ||
* @typedef {import('estree-jsx').JSXSpreadAttribute} EstreeJsxSpreadAttribute | ||
* @typedef {import('estree-jsx').Comment} EstreeComment | ||
* @typedef {import('estree-jsx').Directive} EstreeDirective | ||
* @typedef {import('estree-jsx').Statement} EstreeStatement | ||
* @typedef {import('estree-jsx').ModuleDeclaration} EstreeModuleDeclaration | ||
* @typedef {import('estree-jsx').Expression} EstreeExpression | ||
* @typedef {import('estree-jsx').Property} EstreeProperty | ||
* | ||
* @typedef {EstreeJsxOpeningElement['name']} EstreeJsxElementName | ||
* @typedef {EstreeJsxAttribute['name']} EstreeJsxAttributeName | ||
* @typedef {EstreeJsxElement['children'][number]} EstreeJsxChild | ||
* @typedef {Element['children'][number]} ElementChild | ||
* | ||
* @typedef {Node & {type: 'mdxJsxAttributeValueExpression', value: string}} MDXJsxAttributeValueExpression | ||
* @typedef {Node & {type: 'mdxJsxAttribute', name: string, value: (MDXJsxAttributeValueExpression|string)?}} MDXJsxAttribute | ||
* @typedef {Node & {type: 'mdxJsxExpressionAttribute', value: string}} MDXJsxExpressionAttribute | ||
* @typedef {Parent & {name: string|null, attributes: Array.<MDXJsxExpressionAttribute|MDXJsxAttribute>}} MDXJsxElement | ||
* @typedef {MDXJsxElement & {type: 'mdxJsxFlowElement', children: Array.<MDXJsxFlowElement|ElementChild>}} MDXJsxFlowElement | ||
* @typedef {MDXJsxElement & {type: 'mdxJsxTextElement', children: Array.<MDXJsxTextElement|ElementChild>}} MDXJsxTextElement | ||
* | ||
* @typedef {Node & {value: string}} MDXExpression | ||
* @typedef {MDXExpression & {type: 'mdxFlowExpression'}} MDXFlowExpression | ||
* @typedef {MDXExpression & {type: 'mdxTextExpression'}} MDXTextExpression | ||
* | ||
* @typedef {Node & {type: 'mdxjsEsm', value: string}} MDXEsm | ||
* | ||
* @typedef {ReturnType<find>} Info | ||
* @typedef {'html'|'svg'} Space | ||
* | ||
* @typedef {(node: Node, context: Context) => EstreeJsxChild?} Handle | ||
* | ||
* @typedef Options | ||
* @property {Space} [space='html'] | ||
* @property {Object.<string, Handle>} [handlers={}] | ||
* | ||
* @typedef Context | ||
* @property {typeof html} schema | ||
* @property {Array.<EstreeComment>} comments | ||
* @property {Array.<EstreeDirective|EstreeStatement|EstreeModuleDeclaration>} esm | ||
* @property {Handle} handle | ||
*/ | ||
module.exports = toEstree | ||
import {stringify as commas} from 'comma-separated-tokens' | ||
import {attachComments} from 'estree-util-attach-comments' | ||
import { | ||
start as identifierStart, | ||
cont as identifierCont | ||
} from 'estree-util-is-identifier-name' | ||
import {whitespace} from 'hast-util-whitespace' | ||
import {html, svg, find, hastToReact} from 'property-information' | ||
import {stringify as spaces} from 'space-separated-tokens' | ||
import style from 'style-to-object' | ||
import {position} from 'unist-util-position' | ||
import {zwitch} from 'zwitch' | ||
var commas = require('comma-separated-tokens') | ||
var attachComments = require('estree-util-attach-comments') | ||
var { | ||
start: identifierStart, | ||
cont: identifierCont | ||
} = require('estree-util-is-identifier-name') | ||
var whitespace = require('hast-util-whitespace') | ||
var find = require('property-information/find') | ||
var hastToReact = require('property-information/hast-to-react.json') | ||
var html = require('property-information/html') | ||
var svg = require('property-information/svg') | ||
var spaces = require('space-separated-tokens') | ||
var style = require('style-to-object') | ||
var position = require('unist-util-position') | ||
var zwitch = require('zwitch') | ||
var own = {}.hasOwnProperty | ||
var push = [].push | ||
var handlers = { | ||
comment: comment, | ||
doctype: ignore, | ||
element: element, | ||
mdxjsEsm: mdxjsEsm, | ||
mdxFlowExpression: mdxExpression, | ||
mdxJsxFlowElement: mdxJsxElement, | ||
mdxJsxTextElement: mdxJsxElement, | ||
mdxTextExpression: mdxExpression, | ||
root: root, | ||
text: text | ||
} | ||
function toEstree(tree, options) { | ||
/** | ||
* @param {Node} tree | ||
* @param {Options} options | ||
* @returns {EstreeProgram} | ||
*/ | ||
export function toEstree(tree, options = {}) { | ||
/** @type {Context} */ | ||
var context = { | ||
schema: options && options.space === 'svg' ? svg : html, | ||
schema: options.space === 'svg' ? svg : html, | ||
comments: [], | ||
esm: [], | ||
handle: zwitch('type', { | ||
invalid: invalid, | ||
unknown: unknown, | ||
handlers: Object.assign({}, handlers, options && options.handlers) | ||
invalid, | ||
unknown, | ||
handlers: Object.assign( | ||
{}, | ||
{ | ||
comment, | ||
doctype: ignore, | ||
element, | ||
mdxjsEsm, | ||
mdxFlowExpression: mdxExpression, | ||
mdxJsxFlowElement: mdxJsxElement, | ||
mdxJsxTextElement: mdxJsxElement, | ||
mdxTextExpression: mdxExpression, | ||
root, | ||
text | ||
}, | ||
options.handlers | ||
) | ||
}) | ||
@@ -55,7 +113,3 @@ } | ||
type: 'JSXFragment', | ||
openingFragment: { | ||
type: 'JSXOpeningFragment', | ||
attributes: [], | ||
selfClosing: false | ||
}, | ||
openingFragment: {type: 'JSXOpeningFragment'}, | ||
closingFragment: {type: 'JSXClosingFragment'}, | ||
@@ -66,2 +120,3 @@ children: [result] | ||
// @ts-ignore Types are wrong (`expression` *can* be JSX). | ||
body.push(create(tree, {type: 'ExpressionStatement', expression: result})) | ||
@@ -72,3 +127,3 @@ } | ||
type: 'Program', | ||
body: body, | ||
body, | ||
sourceType: 'module', | ||
@@ -79,2 +134,5 @@ comments: context.comments | ||
/** | ||
* @param {unknown} value | ||
*/ | ||
function invalid(value) { | ||
@@ -84,2 +142,5 @@ throw new Error('Cannot handle value `' + value + '`, expected node') | ||
/** | ||
* @param {Node} node | ||
*/ | ||
function unknown(node) { | ||
@@ -91,2 +152,7 @@ throw new Error('Cannot handle unknown node `' + node.type + '`') | ||
/** | ||
* @param {Comment} node | ||
* @param {Context} context | ||
* @returns {EstreeJsxExpressionContainer} | ||
*/ | ||
function comment(node, context) { | ||
@@ -106,2 +172,7 @@ var esnode = inherit(node, {type: 'Block', value: node.value}) | ||
/** | ||
* @param {Element} node | ||
* @param {Context} context | ||
* @returns {EstreeJsxElement} | ||
*/ | ||
// eslint-disable-next-line complexity | ||
@@ -112,9 +183,20 @@ function element(node, context) { | ||
var props = node.properties || {} | ||
/** @type {Array<EstreeJsxAttribute|EstreeJsxSpreadAttribute>} */ | ||
var attributes = [] | ||
/** @type {Array.<EstreeJsxChild>} */ | ||
var children | ||
/** @type {Info} */ | ||
var info | ||
/** @type {string} */ | ||
var prop | ||
var value | ||
/** @type {string} */ | ||
var cssProp | ||
/** @type {Array.<EstreeProperty>} */ | ||
var cssProperties | ||
/** @type {Properties[string]} */ | ||
var value | ||
/** @type {EstreeJsxAttribute['value']} */ | ||
var attributeValue | ||
/** @type {Object.<string, string>} */ | ||
var styleValue | ||
@@ -129,70 +211,39 @@ if (parentSchema.space === 'html' && node.tagName.toLowerCase() === 'svg') { | ||
for (prop in props) { | ||
value = props[prop] | ||
info = find(schema, prop) | ||
if (own.call(props, prop)) { | ||
value = props[prop] | ||
info = find(schema, prop) | ||
// Ignore nullish and `NaN` values. | ||
// Ignore `false` and falsey known booleans. | ||
if ( | ||
value == null || | ||
value !== value || | ||
value === false || | ||
(!value && info.boolean) | ||
) { | ||
continue | ||
} | ||
// Ignore nullish and `NaN` values. | ||
// Ignore `false` and falsey known booleans. | ||
if ( | ||
value === undefined || | ||
value === null || | ||
(typeof value === 'number' && Number.isNaN(value)) || | ||
value === false || | ||
(!value && info.boolean) | ||
) { | ||
continue | ||
} | ||
prop = info.space | ||
? hastToReact[info.property] || info.property | ||
: info.attribute | ||
prop = info.space | ||
? hastToReact[info.property] || info.property | ||
: info.attribute | ||
if (value && typeof value === 'object' && 'length' in value) { | ||
// Accept `array`. | ||
// Most props are space-separated. | ||
value = (info.commaSeparated ? commas : spaces).stringify(value) | ||
} | ||
if (Array.isArray(value)) { | ||
// Accept `array`. | ||
// Most props are space-separated. | ||
value = info.commaSeparated ? commas(value) : spaces(value) | ||
} | ||
if (prop === 'style' && typeof value === 'string') { | ||
value = parseStyle(value, node.tagName) | ||
} | ||
if (prop === 'style') { | ||
// @ts-ignore Assume `value` is then an object. | ||
styleValue = | ||
typeof value === 'string' ? parseStyle(value, node.tagName) : value | ||
if (value === true) { | ||
value = null | ||
} else if (prop === 'style' && typeof value === 'object') { | ||
cssProperties = [] | ||
cssProperties = [] | ||
for (cssProp in value) { | ||
cssProperties.push({ | ||
type: 'Property', | ||
method: false, | ||
shorthand: false, | ||
computed: false, | ||
key: {type: 'Identifier', name: cssProp}, | ||
value: {type: 'Literal', value: String(value[cssProp])}, | ||
kind: 'init' | ||
}) | ||
} | ||
value = { | ||
type: 'JSXExpressionContainer', | ||
expression: {type: 'ObjectExpression', properties: cssProperties} | ||
} | ||
} else { | ||
value = {type: 'Literal', value: String(value)} | ||
} | ||
if (jsxIdentifierName(prop)) { | ||
attributes.push({ | ||
type: 'JSXAttribute', | ||
name: {type: 'JSXIdentifier', name: prop}, | ||
value: value | ||
}) | ||
} else { | ||
// No need to worry about `style` (which has a `JSXExpressionContainer` | ||
// value) because that’s a valid identifier. | ||
attributes.push({ | ||
type: 'JSXSpreadAttribute', | ||
argument: { | ||
type: 'ObjectExpression', | ||
properties: [ | ||
{ | ||
for (cssProp in styleValue) { | ||
// eslint-disable-next-line max-depth | ||
if (own.call(styleValue, cssProp)) { | ||
cssProperties.push({ | ||
type: 'Property', | ||
@@ -202,9 +253,46 @@ method: false, | ||
computed: false, | ||
key: {type: 'Literal', value: String(prop)}, | ||
value: value || {type: 'Literal', value: true}, | ||
key: {type: 'Identifier', name: cssProp}, | ||
value: {type: 'Literal', value: String(styleValue[cssProp])}, | ||
kind: 'init' | ||
} | ||
] | ||
}) | ||
} | ||
} | ||
}) | ||
attributeValue = { | ||
type: 'JSXExpressionContainer', | ||
expression: {type: 'ObjectExpression', properties: cssProperties} | ||
} | ||
} else if (value === true) { | ||
attributeValue = null | ||
} else { | ||
attributeValue = {type: 'Literal', value: String(value)} | ||
} | ||
if (jsxIdentifierName(prop)) { | ||
attributes.push({ | ||
type: 'JSXAttribute', | ||
name: {type: 'JSXIdentifier', name: prop}, | ||
value: attributeValue | ||
}) | ||
} else { | ||
attributes.push({ | ||
type: 'JSXSpreadAttribute', | ||
argument: { | ||
type: 'ObjectExpression', | ||
properties: [ | ||
{ | ||
type: 'Property', | ||
method: false, | ||
shorthand: false, | ||
computed: false, | ||
key: {type: 'Literal', value: String(prop)}, | ||
// @ts-ignore No need to worry about `style` (which has a `JSXExpressionContainer` | ||
// value) because that’s a valid identifier. | ||
value: attributeValue || {type: 'Literal', value: true}, | ||
kind: 'init' | ||
} | ||
] | ||
} | ||
}) | ||
} | ||
} | ||
@@ -220,14 +308,22 @@ } | ||
type: 'JSXOpeningElement', | ||
attributes: attributes, | ||
attributes, | ||
name: createJsxName(node.tagName), | ||
selfClosing: !children.length | ||
selfClosing: children.length === 0 | ||
}, | ||
closingElement: children.length | ||
? {type: 'JSXClosingElement', name: createJsxName(node.tagName)} | ||
: null, | ||
children: children | ||
closingElement: | ||
children.length > 0 | ||
? {type: 'JSXClosingElement', name: createJsxName(node.tagName)} | ||
: null, | ||
children | ||
}) | ||
} | ||
/** | ||
* @param {MDXEsm} node | ||
* @param {Context} context | ||
* @returns {void} | ||
*/ | ||
function mdxjsEsm(node, context) { | ||
/** @type {EstreeProgram} */ | ||
// @ts-ignore Assume program. | ||
var estree = node.data && node.data.estree | ||
@@ -243,4 +339,12 @@ var comments = (estree && estree.comments) || [] | ||
/** | ||
* @param {MDXFlowExpression|MDXTextExpression} node | ||
* @param {Context} context | ||
* @returns {EstreeJsxExpressionContainer} | ||
*/ | ||
function mdxExpression(node, context) { | ||
/** @type {EstreeProgram} */ | ||
// @ts-ignore Assume program. | ||
var estree = node.data && node.data.estree | ||
/** @type {EstreeExpression} */ | ||
var expression | ||
@@ -251,3 +355,6 @@ | ||
attachComments(estree, estree.comments) | ||
expression = estree.body[0] && estree.body[0].expression | ||
expression = | ||
estree.body[0] && | ||
estree.body[0].type === 'ExpressionStatement' && | ||
estree.body[0].expression | ||
} | ||
@@ -261,2 +368,7 @@ | ||
/** | ||
* @param {MDXJsxFlowElement|MDXJsxTextElement} node | ||
* @param {Context} context | ||
* @returns {EstreeJsxElement|EstreeJsxFragment} | ||
*/ | ||
// eslint-disable-next-line complexity | ||
@@ -267,9 +379,19 @@ function mdxJsxElement(node, context) { | ||
var attrs = node.attributes || [] | ||
var index = -1 | ||
/** @type {Array<EstreeJsxAttribute|EstreeJsxSpreadAttribute>} */ | ||
var attributes = [] | ||
var index = -1 | ||
/** @type {Array.<EstreeJsxChild>} */ | ||
var children | ||
/** @type {MDXJsxExpressionAttribute|MDXJsxAttribute} */ | ||
var attr | ||
/** @type {MDXJsxAttributeValueExpression|string} */ | ||
var value | ||
/** @type {EstreeExpression} */ | ||
var expression | ||
/** @type {EstreeProgram} */ | ||
var estree | ||
/** @type {EstreeJsxAttribute['value']} */ | ||
var attributeValue | ||
/** @type {EstreeJsxSpreadAttribute['argument']} */ | ||
var argumentValue | ||
@@ -292,3 +414,4 @@ if ( | ||
if (attr.type === 'mdxJsxAttribute') { | ||
if (value == null) { | ||
if (value === undefined || value === null) { | ||
attributeValue = null | ||
// Empty. | ||
@@ -298,2 +421,3 @@ } | ||
else if (typeof value === 'object') { | ||
// @ts-ignore Assume program. | ||
estree = value.data && value.data.estree | ||
@@ -305,6 +429,9 @@ expression = null | ||
attachComments(estree, estree.comments) | ||
expression = estree.body[0] && estree.body[0].expression | ||
expression = | ||
estree.body[0] && | ||
estree.body[0].type === 'ExpressionStatement' && | ||
estree.body[0].expression | ||
} | ||
value = inherit(value, { | ||
attributeValue = inherit(value, { | ||
type: 'JSXExpressionContainer', | ||
@@ -316,3 +443,3 @@ expression: expression || {type: 'JSXEmptyExpression'} | ||
else { | ||
value = {type: 'Literal', value: String(value)} | ||
attributeValue = {type: 'Literal', value: String(value)} | ||
} | ||
@@ -323,4 +450,4 @@ | ||
type: 'JSXAttribute', | ||
name: createJsxName(attr.name), | ||
value: value | ||
name: createJsxName(attr.name, true), | ||
value: attributeValue | ||
}) | ||
@@ -331,4 +458,5 @@ ) | ||
else { | ||
// @ts-ignore Assume program. | ||
estree = attr.data && attr.data.estree | ||
value = null | ||
argumentValue = null | ||
@@ -338,7 +466,10 @@ if (estree) { | ||
attachComments(estree, estree.comments) | ||
value = | ||
argumentValue = | ||
estree.body[0] && | ||
estree.body[0].type === 'ExpressionStatement' && | ||
estree.body[0].expression && | ||
estree.body[0].expression.type === 'ObjectExpression' && | ||
estree.body[0].expression.properties && | ||
estree.body[0].expression.properties[0] && | ||
estree.body[0].expression.properties[0].type === 'SpreadElement' && | ||
estree.body[0].expression.properties[0].argument | ||
@@ -350,3 +481,3 @@ } | ||
type: 'JSXSpreadAttribute', | ||
argument: value || {type: 'ObjectExpression', properties: {}} | ||
argument: argumentValue || {type: 'ObjectExpression', properties: []} | ||
}) | ||
@@ -367,20 +498,17 @@ ) | ||
type: 'JSXOpeningElement', | ||
attributes: attributes, | ||
attributes, | ||
name: createJsxName(node.name), | ||
selfClosing: !children.length | ||
selfClosing: children.length === 0 | ||
}, | ||
closingElement: children.length | ||
? {type: 'JSXClosingElement', name: createJsxName(node.name)} | ||
: null, | ||
children: children | ||
closingElement: | ||
children.length > 0 | ||
? {type: 'JSXClosingElement', name: createJsxName(node.name)} | ||
: null, | ||
children | ||
} | ||
: { | ||
type: 'JSXFragment', | ||
openingFragment: { | ||
type: 'JSXOpeningFragment', | ||
attributes: [], | ||
selfClosing: false | ||
}, | ||
openingFragment: {type: 'JSXOpeningFragment'}, | ||
closingFragment: {type: 'JSXClosingFragment'}, | ||
children: children | ||
children | ||
} | ||
@@ -390,21 +518,32 @@ ) | ||
/** | ||
* @param {Root} node | ||
* @param {Context} context | ||
* @returns {EstreeJsxFragment} | ||
*/ | ||
function root(node, context) { | ||
var children = all(node, context) | ||
/** @type {Array.<EstreeJsxChild>} */ | ||
var cleanChildren = [] | ||
var index = -1 | ||
/** @type {Array.<EstreeJsxChild>} */ | ||
var queue | ||
/** @type {EstreeJsxChild} */ | ||
var child | ||
// Remove surrounding whitespace nodes from the fragment. | ||
while (++index < children.length) { | ||
child = children[index] | ||
if ( | ||
children[index].type === 'JSXExpressionContainer' && | ||
children[index].expression.type === 'Literal' && | ||
whitespace(children[index].expression.value) | ||
child.type === 'JSXExpressionContainer' && | ||
child.expression.type === 'Literal' && | ||
whitespace(child.expression.value) | ||
) { | ||
if (queue) { | ||
queue.push(children[index]) | ||
queue.push(child) | ||
} | ||
} else { | ||
push.apply(cleanChildren, queue) | ||
cleanChildren.push(children[index]) | ||
cleanChildren.push(child) | ||
queue = [] | ||
@@ -416,7 +555,3 @@ } | ||
type: 'JSXFragment', | ||
openingFragment: { | ||
type: 'JSXOpeningFragment', | ||
attributes: [], | ||
selfClosing: false | ||
}, | ||
openingFragment: {type: 'JSXOpeningFragment'}, | ||
closingFragment: {type: 'JSXClosingFragment'}, | ||
@@ -427,2 +562,6 @@ children: cleanChildren | ||
/** | ||
* @param {Text} node | ||
* @returns {EstreeJsxExpressionContainer} | ||
*/ | ||
function text(node) { | ||
@@ -435,10 +574,17 @@ var value = String(node.value || '') | ||
type: 'JSXExpressionContainer', | ||
expression: inherit(node, {type: 'Literal', value: value}) | ||
expression: inherit(node, {type: 'Literal', value}) | ||
}) | ||
} | ||
/** | ||
* @param {Parent} parent | ||
* @param {Context} context | ||
* @returns {Array.<EstreeJsxChild>} | ||
*/ | ||
function all(parent, context) { | ||
var children = parent.children || [] | ||
var index = -1 | ||
/** @type {Array.<EstreeJsxChild>} */ | ||
var results = [] | ||
var index = -1 | ||
/** @type {EstreeJsxChild|Array.<EstreeJsxChild>} */ | ||
var result | ||
@@ -448,4 +594,5 @@ | ||
result = context.handle(children[index], context) | ||
if (Array.isArray(result)) { | ||
results = results.concat(result) | ||
results.push(...result) | ||
} else if (result) { | ||
@@ -459,6 +606,15 @@ results.push(result) | ||
// Take positional info and data from `hast`. | ||
/** | ||
* Take positional info and data from `hast`. | ||
* | ||
* @template {EstreeNode|EstreeComment} T | ||
* @param {Node} hast | ||
* @param {T} esnode | ||
* @returns {T} | ||
*/ | ||
function inherit(hast, esnode) { | ||
var left = hast.data | ||
/** @type {Object.<string, unknown>} */ | ||
var right | ||
/** @type {string} */ | ||
var key | ||
@@ -477,2 +633,3 @@ | ||
if (right) { | ||
// @ts-ignore `esast` extension. | ||
esnode.data = right | ||
@@ -485,3 +642,10 @@ } | ||
// Take just positional info. | ||
/** | ||
* Just positional info. | ||
* | ||
* @template {EstreeNode|EstreeComment} T | ||
* @param {Node} hast | ||
* @param {T} esnode | ||
* @returns {T} | ||
*/ | ||
function create(hast, esnode) { | ||
@@ -491,3 +655,5 @@ var p = position(hast) | ||
if (p.start.line) { | ||
// @ts-ignore acorn-style. | ||
esnode.start = p.start.offset | ||
// @ts-ignore acorn-style. | ||
esnode.end = p.end.offset | ||
@@ -504,31 +670,53 @@ esnode.loc = { | ||
function createJsxName(name) { | ||
var parts | ||
var node | ||
const createJsxName = | ||
/** | ||
* @type {( | ||
* ((name: string, attribute: true) => EstreeJsxAttributeName) & | ||
* ((name: string, attribute?: false) => EstreeJsxElementName) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* @param {string} name | ||
* @param {boolean} [attribute=false] | ||
* @returns {EstreeJsxElementName} | ||
*/ | ||
function (name, attribute) { | ||
/** @type {Array.<string>} */ | ||
var parts | ||
/** @type {EstreeJsxElementName} */ | ||
var node | ||
if (name.indexOf('.') > -1) { | ||
parts = name.split('.') | ||
node = {type: 'JSXIdentifier', name: parts.shift()} | ||
while (parts.length) { | ||
node = { | ||
type: 'JSXMemberExpression', | ||
object: node, | ||
property: {type: 'JSXIdentifier', name: parts.shift()} | ||
if (!attribute && name.includes('.')) { | ||
parts = name.split('.') | ||
node = {type: 'JSXIdentifier', name: parts.shift()} | ||
while (parts.length > 0) { | ||
node = { | ||
type: 'JSXMemberExpression', | ||
object: node, | ||
property: {type: 'JSXIdentifier', name: parts.shift()} | ||
} | ||
} | ||
} else if (name.includes(':')) { | ||
parts = name.split(':') | ||
node = { | ||
type: 'JSXNamespacedName', | ||
namespace: {type: 'JSXIdentifier', name: parts[0]}, | ||
name: {type: 'JSXIdentifier', name: parts[1]} | ||
} | ||
} else { | ||
node = {type: 'JSXIdentifier', name} | ||
} | ||
return node | ||
} | ||
} else if (name.indexOf(':') > -1) { | ||
parts = name.split(':') | ||
node = { | ||
type: 'JSXNamespacedName', | ||
namespace: {type: 'JSXIdentifier', name: parts[0]}, | ||
name: {type: 'JSXIdentifier', name: parts[1]} | ||
} | ||
} else { | ||
node = {type: 'JSXIdentifier', name: name} | ||
} | ||
) | ||
return node | ||
} | ||
/** | ||
* @param {string} value | ||
* @param {string} tagName | ||
* @returns {Object.<string, string>} | ||
*/ | ||
function parseStyle(value, tagName) { | ||
/** @type {Object.<string, string>} */ | ||
var result = {} | ||
@@ -546,2 +734,7 @@ | ||
/** | ||
* @param {string} name | ||
* @param {string} value | ||
* @returns {void} | ||
*/ | ||
function iterator(name, value) { | ||
@@ -553,3 +746,8 @@ if (name.slice(0, 4) === '-ms-') name = 'ms-' + name.slice(4) | ||
function styleReplacer($0, $1) { | ||
/** | ||
* @param {string} _ | ||
* @param {string} $1 | ||
* @returns {string} | ||
*/ | ||
function styleReplacer(_, $1) { | ||
return $1.toUpperCase() | ||
@@ -562,2 +760,3 @@ } | ||
* @param {string} name | ||
* @returns {boolean} | ||
*/ | ||
@@ -574,2 +773,6 @@ function jsxIdentifierName(name) { | ||
/** | ||
* @param {number} code | ||
* @returns {boolean} | ||
*/ | ||
function cont(code) { | ||
@@ -576,0 +779,0 @@ return identifierCont(code) || code === 45 /* `-` */ |
{ | ||
"name": "hast-util-to-estree", | ||
"version": "1.4.0", | ||
"version": "2.0.0", | ||
"description": "hast utility to transform to estree (JavaScript AST) JSX", | ||
@@ -33,15 +33,23 @@ "license": "MIT", | ||
], | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"index.d.ts", | ||
"index.js" | ||
], | ||
"dependencies": { | ||
"comma-separated-tokens": "^1.0.0", | ||
"estree-util-attach-comments": "^1.0.0", | ||
"estree-util-is-identifier-name": "^1.1.0", | ||
"hast-util-whitespace": "^1.0.0", | ||
"property-information": "^5.0.0", | ||
"space-separated-tokens": "^1.0.0", | ||
"@types/estree-jsx": "^0.0.1", | ||
"@types/hast": "^2.0.0", | ||
"@types/unist": "^2.0.0", | ||
"comma-separated-tokens": "^2.0.0", | ||
"estree-util-attach-comments": "^2.0.0", | ||
"estree-util-is-identifier-name": "^2.0.0", | ||
"hast-util-whitespace": "^2.0.0", | ||
"property-information": "^6.0.0", | ||
"space-separated-tokens": "^2.0.0", | ||
"style-to-object": "^0.3.0", | ||
"unist-util-position": "^3.1.0", | ||
"zwitch": "^1.0.0" | ||
"unist-util-position": "^4.0.0", | ||
"zwitch": "^2.0.0" | ||
}, | ||
@@ -52,15 +60,17 @@ "devDependencies": { | ||
"@babel/plugin-transform-react-jsx": "^7.0.0", | ||
"@types/babel__core": "^7.0.0", | ||
"@types/tape": "^4.0.0", | ||
"@vue/babel-plugin-jsx": "^1.0.0", | ||
"acorn": "^8.0.0", | ||
"acorn-jsx": "^5.0.0", | ||
"c8": "^7.0.0", | ||
"estree-to-babel": "^3.0.0", | ||
"estree-util-build-jsx": "^1.0.0", | ||
"hast-util-from-parse5": "^6.0.1", | ||
"hastscript": "^6.0.0", | ||
"estree-util-build-jsx": "^2.0.0", | ||
"hast-util-from-parse5": "^6.0.0", | ||
"hastscript": "^7.0.0", | ||
"mdast-util-from-markdown": "^0.8.0", | ||
"mdast-util-mdx": "^0.1.0", | ||
"mdast-util-to-hast": "^10.1.0", | ||
"mdast-util-to-hast": "^11.0.0", | ||
"micromark-extension-mdxjs": "^0.3.0", | ||
"nyc": "^15.0.0", | ||
"parse5": "^6.0.1", | ||
"parse5": "^6.0.0", | ||
"prettier": "^2.0.0", | ||
@@ -70,18 +80,18 @@ "recast": "^0.20.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"unist-util-visit": "^2.0.0", | ||
"xo": "^0.38.0" | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-util-visit": "^3.0.0", | ||
"vfile": "^4.0.0", | ||
"xo": "^0.39.0" | ||
}, | ||
"scripts": { | ||
"prepack": "npm run build && npm run format", | ||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test.js", | ||
"test": "npm run format && npm run test-coverage" | ||
"test-api": "node test.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"nyc": { | ||
"check-coverage": true, | ||
"lines": 100, | ||
"functions": 100, | ||
"branches": 100 | ||
}, | ||
"prettier": { | ||
@@ -97,20 +107,5 @@ "tabWidth": 2, | ||
"prettier": true, | ||
"esnext": false, | ||
"rules": { | ||
"eqeqeq": [ | ||
"error", | ||
"always", | ||
{ | ||
"null": "ignore" | ||
} | ||
], | ||
"guard-for-in": "off", | ||
"max-depth": "off", | ||
"no-eq-null": "off", | ||
"no-self-compare": "off", | ||
"unicorn/explicit-length-check": "off", | ||
"unicorn/no-array-for-each": "off", | ||
"unicorn/no-array-callback-reference": "off", | ||
"unicorn/prefer-includes": "off", | ||
"unicorn/prefer-number-properties": "off" | ||
"no-var": "off", | ||
"prefer-arrow-callback": "off" | ||
} | ||
@@ -122,3 +117,9 @@ }, | ||
] | ||
}, | ||
"typeCoverage": { | ||
"atLeast": 100, | ||
"detail": true, | ||
"strict": true, | ||
"ignoreCatch": true | ||
} | ||
} |
@@ -15,2 +15,5 @@ # hast-util-to-estree | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
[npm][]: | ||
@@ -49,7 +52,7 @@ | ||
```js | ||
var fs = require('fs') | ||
var parse5 = require('parse5') | ||
var fromParse5 = require('hast-util-from-parse5') | ||
var toEstree = require('hast-util-to-estree') | ||
var recast = require('recast') | ||
import fs from 'fs' | ||
import parse5 from 'parse5' | ||
import {fromParse5} from 'hast-util-from-parse5' | ||
import {toEstree} from 'hast-util-to-estree' | ||
import recast from 'recast' | ||
@@ -105,2 +108,5 @@ var hast = fromParse5(parse5.parse(String(fs.readFileSync('example.html')))) | ||
This package exports the following identifiers: `toEstree`. | ||
There is no default export. | ||
### `toEstree(tree, options?)` | ||
@@ -107,0 +113,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33731
5
755
232
Yes
12
29
+ Added@types/estree-jsx@^0.0.1
+ Added@types/hast@^2.0.0
+ Added@types/unist@^2.0.0
+ Added@types/estree@1.0.6(transitive)
+ Added@types/estree-jsx@0.0.1(transitive)
+ Added@types/hast@2.3.10(transitive)
+ Added@types/unist@2.0.11(transitive)
+ Addedcomma-separated-tokens@2.0.3(transitive)
+ Addedestree-util-attach-comments@2.1.1(transitive)
+ Addedestree-util-is-identifier-name@2.1.0(transitive)
+ Addedhast-util-whitespace@2.0.1(transitive)
+ Addedproperty-information@6.5.0(transitive)
+ Addedspace-separated-tokens@2.0.2(transitive)
+ Addedunist-util-position@4.0.4(transitive)
+ Addedzwitch@2.0.4(transitive)
- Removedcomma-separated-tokens@1.0.8(transitive)
- Removedestree-util-attach-comments@1.0.0(transitive)
- Removedestree-util-is-identifier-name@1.1.0(transitive)
- Removedhast-util-whitespace@1.0.4(transitive)
- Removedproperty-information@5.6.0(transitive)
- Removedspace-separated-tokens@1.1.5(transitive)
- Removedunist-util-position@3.1.0(transitive)
- Removedxtend@4.0.2(transitive)
- Removedzwitch@1.0.5(transitive)
Updatedhast-util-whitespace@^2.0.0
Updatedproperty-information@^6.0.0
Updatedunist-util-position@^4.0.0
Updatedzwitch@^2.0.0