diff --git a/index.cjs b/index.cjs
new file mode 100644
index 0000000..e1bc0ab
--- /dev/null
+++ b/index.cjs
@@ -0,0 +1,767 @@
+// DO NOT edit this file, it's auto-generated from 'rollup.config.js'; any changes will be overwritten.
+
+'use strict';
+
+var acorn = require('acorn');
+
+function _interopNamespace(e) {
+ if (e && e.__esModule) return e;
+ var n = Object.create(null);
+ if (e) {
+ Object.keys(e).forEach(function (k) {
+ if (k !== 'default') {
+ var d = Object.getOwnPropertyDescriptor(e, k);
+ Object.defineProperty(n, k, d.get ? d : {
+ enumerable: true,
+ get: function () { return e[k]; }
+ });
+ }
+ });
+ }
+ n["default"] = e;
+ return Object.freeze(n);
+}
+
+var acorn__namespace = /*#__PURE__*/_interopNamespace(acorn);
+
+var XHTMLEntities = {
+ quot: '\u0022',
+ amp: '&',
+ apos: '\u0027',
+ lt: '<',
+ gt: '>',
+ nbsp: '\u00A0',
+ iexcl: '\u00A1',
+ cent: '\u00A2',
+ pound: '\u00A3',
+ curren: '\u00A4',
+ yen: '\u00A5',
+ brvbar: '\u00A6',
+ sect: '\u00A7',
+ uml: '\u00A8',
+ copy: '\u00A9',
+ ordf: '\u00AA',
+ laquo: '\u00AB',
+ not: '\u00AC',
+ shy: '\u00AD',
+ reg: '\u00AE',
+ macr: '\u00AF',
+ deg: '\u00B0',
+ plusmn: '\u00B1',
+ sup2: '\u00B2',
+ sup3: '\u00B3',
+ acute: '\u00B4',
+ micro: '\u00B5',
+ para: '\u00B6',
+ middot: '\u00B7',
+ cedil: '\u00B8',
+ sup1: '\u00B9',
+ ordm: '\u00BA',
+ raquo: '\u00BB',
+ frac14: '\u00BC',
+ frac12: '\u00BD',
+ frac34: '\u00BE',
+ iquest: '\u00BF',
+ Agrave: '\u00C0',
+ Aacute: '\u00C1',
+ Acirc: '\u00C2',
+ Atilde: '\u00C3',
+ Auml: '\u00C4',
+ Aring: '\u00C5',
+ AElig: '\u00C6',
+ Ccedil: '\u00C7',
+ Egrave: '\u00C8',
+ Eacute: '\u00C9',
+ Ecirc: '\u00CA',
+ Euml: '\u00CB',
+ Igrave: '\u00CC',
+ Iacute: '\u00CD',
+ Icirc: '\u00CE',
+ Iuml: '\u00CF',
+ ETH: '\u00D0',
+ Ntilde: '\u00D1',
+ Ograve: '\u00D2',
+ Oacute: '\u00D3',
+ Ocirc: '\u00D4',
+ Otilde: '\u00D5',
+ Ouml: '\u00D6',
+ times: '\u00D7',
+ Oslash: '\u00D8',
+ Ugrave: '\u00D9',
+ Uacute: '\u00DA',
+ Ucirc: '\u00DB',
+ Uuml: '\u00DC',
+ Yacute: '\u00DD',
+ THORN: '\u00DE',
+ szlig: '\u00DF',
+ agrave: '\u00E0',
+ aacute: '\u00E1',
+ acirc: '\u00E2',
+ atilde: '\u00E3',
+ auml: '\u00E4',
+ aring: '\u00E5',
+ aelig: '\u00E6',
+ ccedil: '\u00E7',
+ egrave: '\u00E8',
+ eacute: '\u00E9',
+ ecirc: '\u00EA',
+ euml: '\u00EB',
+ igrave: '\u00EC',
+ iacute: '\u00ED',
+ icirc: '\u00EE',
+ iuml: '\u00EF',
+ eth: '\u00F0',
+ ntilde: '\u00F1',
+ ograve: '\u00F2',
+ oacute: '\u00F3',
+ ocirc: '\u00F4',
+ otilde: '\u00F5',
+ ouml: '\u00F6',
+ divide: '\u00F7',
+ oslash: '\u00F8',
+ ugrave: '\u00F9',
+ uacute: '\u00FA',
+ ucirc: '\u00FB',
+ uuml: '\u00FC',
+ yacute: '\u00FD',
+ thorn: '\u00FE',
+ yuml: '\u00FF',
+ OElig: '\u0152',
+ oelig: '\u0153',
+ Scaron: '\u0160',
+ scaron: '\u0161',
+ Yuml: '\u0178',
+ fnof: '\u0192',
+ circ: '\u02C6',
+ tilde: '\u02DC',
+ Alpha: '\u0391',
+ Beta: '\u0392',
+ Gamma: '\u0393',
+ Delta: '\u0394',
+ Epsilon: '\u0395',
+ Zeta: '\u0396',
+ Eta: '\u0397',
+ Theta: '\u0398',
+ Iota: '\u0399',
+ Kappa: '\u039A',
+ Lambda: '\u039B',
+ Mu: '\u039C',
+ Nu: '\u039D',
+ Xi: '\u039E',
+ Omicron: '\u039F',
+ Pi: '\u03A0',
+ Rho: '\u03A1',
+ Sigma: '\u03A3',
+ Tau: '\u03A4',
+ Upsilon: '\u03A5',
+ Phi: '\u03A6',
+ Chi: '\u03A7',
+ Psi: '\u03A8',
+ Omega: '\u03A9',
+ alpha: '\u03B1',
+ beta: '\u03B2',
+ gamma: '\u03B3',
+ delta: '\u03B4',
+ epsilon: '\u03B5',
+ zeta: '\u03B6',
+ eta: '\u03B7',
+ theta: '\u03B8',
+ iota: '\u03B9',
+ kappa: '\u03BA',
+ lambda: '\u03BB',
+ mu: '\u03BC',
+ nu: '\u03BD',
+ xi: '\u03BE',
+ omicron: '\u03BF',
+ pi: '\u03C0',
+ rho: '\u03C1',
+ sigmaf: '\u03C2',
+ sigma: '\u03C3',
+ tau: '\u03C4',
+ upsilon: '\u03C5',
+ phi: '\u03C6',
+ chi: '\u03C7',
+ psi: '\u03C8',
+ omega: '\u03C9',
+ thetasym: '\u03D1',
+ upsih: '\u03D2',
+ piv: '\u03D6',
+ ensp: '\u2002',
+ emsp: '\u2003',
+ thinsp: '\u2009',
+ zwnj: '\u200C',
+ zwj: '\u200D',
+ lrm: '\u200E',
+ rlm: '\u200F',
+ ndash: '\u2013',
+ mdash: '\u2014',
+ lsquo: '\u2018',
+ rsquo: '\u2019',
+ sbquo: '\u201A',
+ ldquo: '\u201C',
+ rdquo: '\u201D',
+ bdquo: '\u201E',
+ dagger: '\u2020',
+ Dagger: '\u2021',
+ bull: '\u2022',
+ hellip: '\u2026',
+ permil: '\u2030',
+ prime: '\u2032',
+ Prime: '\u2033',
+ lsaquo: '\u2039',
+ rsaquo: '\u203A',
+ oline: '\u203E',
+ frasl: '\u2044',
+ euro: '\u20AC',
+ image: '\u2111',
+ weierp: '\u2118',
+ real: '\u211C',
+ trade: '\u2122',
+ alefsym: '\u2135',
+ larr: '\u2190',
+ uarr: '\u2191',
+ rarr: '\u2192',
+ darr: '\u2193',
+ harr: '\u2194',
+ crarr: '\u21B5',
+ lArr: '\u21D0',
+ uArr: '\u21D1',
+ rArr: '\u21D2',
+ dArr: '\u21D3',
+ hArr: '\u21D4',
+ forall: '\u2200',
+ part: '\u2202',
+ exist: '\u2203',
+ empty: '\u2205',
+ nabla: '\u2207',
+ isin: '\u2208',
+ notin: '\u2209',
+ ni: '\u220B',
+ prod: '\u220F',
+ sum: '\u2211',
+ minus: '\u2212',
+ lowast: '\u2217',
+ radic: '\u221A',
+ prop: '\u221D',
+ infin: '\u221E',
+ ang: '\u2220',
+ and: '\u2227',
+ or: '\u2228',
+ cap: '\u2229',
+ cup: '\u222A',
+ 'int': '\u222B',
+ there4: '\u2234',
+ sim: '\u223C',
+ cong: '\u2245',
+ asymp: '\u2248',
+ ne: '\u2260',
+ equiv: '\u2261',
+ le: '\u2264',
+ ge: '\u2265',
+ sub: '\u2282',
+ sup: '\u2283',
+ nsub: '\u2284',
+ sube: '\u2286',
+ supe: '\u2287',
+ oplus: '\u2295',
+ otimes: '\u2297',
+ perp: '\u22A5',
+ sdot: '\u22C5',
+ lceil: '\u2308',
+ rceil: '\u2309',
+ lfloor: '\u230A',
+ rfloor: '\u230B',
+ lang: '\u2329',
+ rang: '\u232A',
+ loz: '\u25CA',
+ spades: '\u2660',
+ clubs: '\u2663',
+ hearts: '\u2665',
+ diams: '\u2666'
+};
+
+const hexNumber = /^[\da-fA-F]+$/;
+const decimalNumber = /^\d+$/;
+
+// The map to `acorn-jsx` tokens from `acorn` namespace objects.
+const acornJsxMap = new WeakMap();
+
+// Get the original tokens for the given `acorn` namespace object.
+function getJsxTokens(acorn) {
+ acorn = acorn.Parser.acorn || acorn;
+ let acornJsx = acornJsxMap.get(acorn);
+ if (!acornJsx) {
+ const tt = acorn.tokTypes;
+ const TokContext = acorn.TokContext;
+ const TokenType = acorn.TokenType;
+ const tc_oTag = new TokContext('...', true, true);
+ const tokContexts = {
+ tc_oTag: tc_oTag,
+ tc_cTag: tc_cTag,
+ tc_expr: tc_expr
+ };
+ const tokTypes = {
+ jsxName: new TokenType('jsxName'),
+ jsxText: new TokenType('jsxText', {beforeExpr: true}),
+ jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}),
+ jsxTagEnd: new TokenType('jsxTagEnd')
+ };
+
+ tokTypes.jsxTagStart.updateContext = function() {
+ this.context.push(tc_expr); // treat as beginning of JSX expression
+ this.context.push(tc_oTag); // start opening tag context
+ this.exprAllowed = false;
+ };
+ tokTypes.jsxTagEnd.updateContext = function(prevType) {
+ let out = this.context.pop();
+ if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) {
+ this.context.pop();
+ this.exprAllowed = this.curContext() === tc_expr;
+ } else {
+ this.exprAllowed = true;
+ }
+ };
+
+ acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes };
+ acornJsxMap.set(acorn, acornJsx);
+ }
+
+ return acornJsx;
+}
+
+// Transforms JSX element name to string.
+
+function getQualifiedJSXName(object) {
+ if (!object)
+ return object;
+
+ if (object.type === 'JSXIdentifier')
+ return object.name;
+
+ if (object.type === 'JSXNamespacedName')
+ return object.namespace.name + ':' + object.name.name;
+
+ if (object.type === 'JSXMemberExpression')
+ return getQualifiedJSXName(object.object) + '.' +
+ getQualifiedJSXName(object.property);
+}
+
+function acornJsx(options) {
+ options = options || {};
+ return function(Parser) {
+ return plugin({
+ allowNamespaces: options.allowNamespaces !== false,
+ allowNamespacedObjects: !!options.allowNamespacedObjects
+ }, Parser);
+ };
+}
+// This is `tokTypes` of the peer dep.
+// This can be different instances from the actual `tokTypes` this plugin uses.
+Object.defineProperty(acornJsx, "tokTypes", {
+ get: function get_tokTypes() {
+ return getJsxTokens(acorn__namespace).tokTypes;
+ },
+ configurable: true,
+ enumerable: true
+});
+
+function plugin(options, Parser) {
+ const acrn = Parser.acorn || acorn__namespace;
+ const acornJsx = getJsxTokens(acorn__namespace);
+ const tt = acrn.tokTypes;
+ const tok = acornJsx.tokTypes;
+ const tokContexts = acrn.tokContexts;
+ const tc_oTag = acornJsx.tokContexts.tc_oTag;
+ const tc_cTag = acornJsx.tokContexts.tc_cTag;
+ const tc_expr = acornJsx.tokContexts.tc_expr;
+ const isNewLine = acrn.isNewLine;
+ const isIdentifierStart = acrn.isIdentifierStart;
+ const isIdentifierChar = acrn.isIdentifierChar;
+
+ return class extends Parser {
+ // Expose actual `tokTypes` and `tokContexts` to other plugins.
+ static get acornJsx() {
+ return acornJsx;
+ }
+
+ // Reads inline JSX contents token.
+ jsx_readToken() {
+ let out = '', chunkStart = this.pos;
+ for (;;) {
+ if (this.pos >= this.input.length)
+ this.raise(this.start, 'Unterminated JSX contents');
+ let ch = this.input.charCodeAt(this.pos);
+
+ switch (ch) {
+ case 60: // '<'
+ case 123: // '{'
+ if (this.pos === this.start) {
+ if (ch === 60 && this.exprAllowed) {
+ ++this.pos;
+ return this.finishToken(tok.jsxTagStart);
+ }
+ return this.getTokenFromCode(ch);
+ }
+ out += this.input.slice(chunkStart, this.pos);
+ return this.finishToken(tok.jsxText, out);
+
+ case 38: // '&'
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.jsx_readEntity();
+ chunkStart = this.pos;
+ break;
+
+ case 62: // '>'
+ case 125: // '}'
+ this.raise(
+ this.pos,
+ "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" +
+ (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?"
+ );
+
+ default:
+ if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.jsx_readNewLine(true);
+ chunkStart = this.pos;
+ } else {
+ ++this.pos;
+ }
+ }
+ }
+ }
+
+ jsx_readNewLine(normalizeCRLF) {
+ let ch = this.input.charCodeAt(this.pos);
+ let out;
+ ++this.pos;
+ if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
+ ++this.pos;
+ out = normalizeCRLF ? '\n' : '\r\n';
+ } else {
+ out = String.fromCharCode(ch);
+ }
+ if (this.options.locations) {
+ ++this.curLine;
+ this.lineStart = this.pos;
+ }
+
+ return out;
+ }
+
+ jsx_readString(quote) {
+ let out = '', chunkStart = ++this.pos;
+ for (;;) {
+ if (this.pos >= this.input.length)
+ this.raise(this.start, 'Unterminated string constant');
+ let ch = this.input.charCodeAt(this.pos);
+ if (ch === quote) break;
+ if (ch === 38) { // '&'
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.jsx_readEntity();
+ chunkStart = this.pos;
+ } else if (isNewLine(ch)) {
+ out += this.input.slice(chunkStart, this.pos);
+ out += this.jsx_readNewLine(false);
+ chunkStart = this.pos;
+ } else {
+ ++this.pos;
+ }
+ }
+ out += this.input.slice(chunkStart, this.pos++);
+ return this.finishToken(tt.string, out);
+ }
+
+ jsx_readEntity() {
+ let str = '', count = 0, entity;
+ let ch = this.input[this.pos];
+ if (ch !== '&')
+ this.raise(this.pos, 'Entity must start with an ampersand');
+ let startPos = ++this.pos;
+ while (this.pos < this.input.length && count++ < 10) {
+ ch = this.input[this.pos++];
+ if (ch === ';') {
+ if (str[0] === '#') {
+ if (str[1] === 'x') {
+ str = str.substr(2);
+ if (hexNumber.test(str))
+ entity = String.fromCharCode(parseInt(str, 16));
+ } else {
+ str = str.substr(1);
+ if (decimalNumber.test(str))
+ entity = String.fromCharCode(parseInt(str, 10));
+ }
+ } else {
+ entity = XHTMLEntities[str];
+ }
+ break;
+ }
+ str += ch;
+ }
+ if (!entity) {
+ this.pos = startPos;
+ return '&';
+ }
+ return entity;
+ }
+
+ // Read a JSX identifier (valid tag or attribute name).
+ //
+ // Optimized version since JSX identifiers can't contain
+ // escape characters and so can be read as single slice.
+ // Also assumes that first character was already checked
+ // by isIdentifierStart in readToken.
+
+ jsx_readWord() {
+ let ch, start = this.pos;
+ do {
+ ch = this.input.charCodeAt(++this.pos);
+ } while (isIdentifierChar(ch) || ch === 45); // '-'
+ return this.finishToken(tok.jsxName, this.input.slice(start, this.pos));
+ }
+
+ // Parse next token as JSX identifier
+
+ jsx_parseIdentifier() {
+ let node = this.startNode();
+ if (this.type === tok.jsxName)
+ node.name = this.value;
+ else if (this.type.keyword)
+ node.name = this.type.keyword;
+ else
+ this.unexpected();
+ this.next();
+ return this.finishNode(node, 'JSXIdentifier');
+ }
+
+ // Parse namespaced identifier.
+
+ jsx_parseNamespacedName() {
+ let startPos = this.start, startLoc = this.startLoc;
+ let name = this.jsx_parseIdentifier();
+ if (!options.allowNamespaces || !this.eat(tt.colon)) return name;
+ var node = this.startNodeAt(startPos, startLoc);
+ node.namespace = name;
+ node.name = this.jsx_parseIdentifier();
+ return this.finishNode(node, 'JSXNamespacedName');
+ }
+
+ // Parses element name in any form - namespaced, member
+ // or single identifier.
+
+ jsx_parseElementName() {
+ if (this.type === tok.jsxTagEnd) return '';
+ let startPos = this.start, startLoc = this.startLoc;
+ let node = this.jsx_parseNamespacedName();
+ if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) {
+ this.unexpected();
+ }
+ while (this.eat(tt.dot)) {
+ let newNode = this.startNodeAt(startPos, startLoc);
+ newNode.object = node;
+ newNode.property = this.jsx_parseIdentifier();
+ node = this.finishNode(newNode, 'JSXMemberExpression');
+ }
+ return node;
+ }
+
+ // Parses any type of JSX attribute value.
+
+ jsx_parseAttributeValue() {
+ switch (this.type) {
+ case tt.braceL:
+ let node = this.jsx_parseExpressionContainer();
+ if (node.expression.type === 'JSXEmptyExpression')
+ this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression');
+ return node;
+
+ case tok.jsxTagStart:
+ case tt.string:
+ return this.parseExprAtom();
+
+ default:
+ this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text');
+ }
+ }
+
+ // JSXEmptyExpression is unique type since it doesn't actually parse anything,
+ // and so it should start at the end of last read token (left brace) and finish
+ // at the beginning of the next one (right brace).
+
+ jsx_parseEmptyExpression() {
+ let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
+ return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc);
+ }
+
+ // Parses JSX expression enclosed into curly brackets.
+
+ jsx_parseExpressionContainer() {
+ let node = this.startNode();
+ this.next();
+ node.expression = this.type === tt.braceR
+ ? this.jsx_parseEmptyExpression()
+ : this.parseExpression();
+ this.expect(tt.braceR);
+ return this.finishNode(node, 'JSXExpressionContainer');
+ }
+
+ // Parses following JSX attribute name-value pair.
+
+ jsx_parseAttribute() {
+ let node = this.startNode();
+ if (this.eat(tt.braceL)) {
+ this.expect(tt.ellipsis);
+ node.argument = this.parseMaybeAssign();
+ this.expect(tt.braceR);
+ return this.finishNode(node, 'JSXSpreadAttribute');
+ }
+ node.name = this.jsx_parseNamespacedName();
+ node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
+ return this.finishNode(node, 'JSXAttribute');
+ }
+
+ // Parses JSX opening tag starting after '<'.
+
+ jsx_parseOpeningElementAt(startPos, startLoc) {
+ let node = this.startNodeAt(startPos, startLoc);
+ node.attributes = [];
+ let nodeName = this.jsx_parseElementName();
+ if (nodeName) node.name = nodeName;
+ while (this.type !== tt.slash && this.type !== tok.jsxTagEnd)
+ node.attributes.push(this.jsx_parseAttribute());
+ node.selfClosing = this.eat(tt.slash);
+ this.expect(tok.jsxTagEnd);
+ return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment');
+ }
+
+ // Parses JSX closing tag starting after ''.
+
+ jsx_parseClosingElementAt(startPos, startLoc) {
+ let node = this.startNodeAt(startPos, startLoc);
+ let nodeName = this.jsx_parseElementName();
+ if (nodeName) node.name = nodeName;
+ this.expect(tok.jsxTagEnd);
+ return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment');
+ }
+
+ // Parses entire JSX element, including it's opening tag
+ // (starting after '<'), attributes, contents and closing tag.
+
+ jsx_parseElementAt(startPos, startLoc) {
+ let node = this.startNodeAt(startPos, startLoc);
+ let children = [];
+ let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc);
+ let closingElement = null;
+
+ if (!openingElement.selfClosing) {
+ contents: for (;;) {
+ switch (this.type) {
+ case tok.jsxTagStart:
+ startPos = this.start; startLoc = this.startLoc;
+ this.next();
+ if (this.eat(tt.slash)) {
+ closingElement = this.jsx_parseClosingElementAt(startPos, startLoc);
+ break contents;
+ }
+ children.push(this.jsx_parseElementAt(startPos, startLoc));
+ break;
+
+ case tok.jsxText:
+ children.push(this.parseExprAtom());
+ break;
+
+ case tt.braceL:
+ children.push(this.jsx_parseExpressionContainer());
+ break;
+
+ default:
+ this.unexpected();
+ }
+ }
+ if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
+ this.raise(
+ closingElement.start,
+ 'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>');
+ }
+ }
+ let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment';
+
+ node['opening' + fragmentOrElement] = openingElement;
+ node['closing' + fragmentOrElement] = closingElement;
+ node.children = children;
+ if (this.type === tt.relational && this.value === "<") {
+ this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
+ }
+ return this.finishNode(node, 'JSX' + fragmentOrElement);
+ }
+
+ // Parse JSX text
+
+ jsx_parseText() {
+ let node = this.parseLiteral(this.value);
+ node.type = "JSXText";
+ return node;
+ }
+
+ // Parses entire JSX element from current position.
+
+ jsx_parseElement() {
+ let startPos = this.start, startLoc = this.startLoc;
+ this.next();
+ return this.jsx_parseElementAt(startPos, startLoc);
+ }
+
+ parseExprAtom(refShortHandDefaultPos) {
+ if (this.type === tok.jsxText)
+ return this.jsx_parseText();
+ else if (this.type === tok.jsxTagStart)
+ return this.jsx_parseElement();
+ else
+ return super.parseExprAtom(refShortHandDefaultPos);
+ }
+
+ readToken(code) {
+ let context = this.curContext();
+
+ if (context === tc_expr) return this.jsx_readToken();
+
+ if (context === tc_oTag || context === tc_cTag) {
+ if (isIdentifierStart(code)) return this.jsx_readWord();
+
+ if (code == 62) {
+ ++this.pos;
+ return this.finishToken(tok.jsxTagEnd);
+ }
+
+ if ((code === 34 || code === 39) && context == tc_oTag)
+ return this.jsx_readString(code);
+ }
+
+ if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) {
+ ++this.pos;
+ return this.finishToken(tok.jsxTagStart);
+ }
+ return super.readToken(code);
+ }
+
+ updateContext(prevType) {
+ if (this.type == tt.braceL) {
+ var curContext = this.curContext();
+ if (curContext == tc_oTag) this.context.push(tokContexts.b_expr);
+ else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl);
+ else super.updateContext(prevType);
+ this.exprAllowed = true;
+ } else if (this.type === tt.slash && prevType === tok.jsxTagStart) {
+ this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
+ this.context.push(tc_cTag); // reconsider as closing tag context
+ this.exprAllowed = false;
+ } else {
+ return super.updateContext(prevType);
+ }
+ }
+ };
+}
+
+module.exports = acornJsx;
diff --git a/index.d.cts b/index.d.cts
new file mode 100644
index 0000000..0a2803d
--- /dev/null
+++ b/index.d.cts
@@ -0,0 +1,3 @@
+import * as jsx from './index.js';
+
+export = jsx;
diff --git a/index.d.ts b/index.d.ts
index 66ef62f..5a0f90d 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -1,47 +1,49 @@
import * as acorn from 'acorn';
-interface JsxTokTypes extends AcornTokTypes {
+export declare class TokContext {
+ constructor(
+ token: string,
+ isExpr: boolean,
+ preserveSpace: boolean,
+ override?: (parser: any) => void
+ )
+}
+
+export interface JsxTokTypes extends AcornTokTypes {
jsxName: acorn.TokenType,
jsxText: acorn.TokenType,
jsxTagEnd: acorn.TokenType,
jsxTagStart: acorn.TokenType
}
-declare const jsx: {
- tokTypes: JsxTokTypes;
- (options?: jsx.Options): (BaseParser: typeof acorn.Parser) => jsx.AcornJsxParserCtor
-}
-
-type AcornTokTypes = typeof acorn.tokTypes;
-
-declare namespace jsx {
+export type AcornTokTypes = typeof acorn.tokTypes;
- type TokTypes = JsxTokTypes
+export type TokTypes = JsxTokTypes
- interface Options {
+export interface Options {
allowNamespacedObjects?: boolean;
allowNamespaces?: boolean;
- }
+}
- interface TokContexts {
- tc_oTag: acorn.TokContext,
- tc_cTag: acorn.TokContext,
- tc_expr: acorn.TokContext
- }
+export interface TokContexts {
+ tc_oTag: TokContext,
+ tc_cTag: TokContext,
+ tc_expr: TokContext
+}
- // We pick (statics) from acorn rather than plain extending to avoid complaint
- // about base constructors needing the same return type (i.e., we return
- // `AcornJsxParser` here)
- interface AcornJsxParserCtor extends Pick {
+// We pick (statics) from acorn rather than plain extending to avoid complaint
+// about base constructors needing the same return type (i.e., we return
+// `AcornJsxParser` here)
+export interface AcornJsxParserCtor extends Pick {
readonly acornJsx: {
- tokTypes: TokTypes;
- tokContexts: TokContexts
+ tokTypes: TokTypes;
+ tokContexts: TokContexts
};
new (options: acorn.Options, input: string, startPos?: number): AcornJsxParser;
- }
+}
- interface AcornJsxParser extends acorn.Parser {
+export interface AcornJsxParser extends acorn.Parser {
jsx_readToken(): string;
jsx_readNewLine(normalizeCRLF: boolean): void;
jsx_readString(quote: number): void;
@@ -59,7 +61,16 @@ declare namespace jsx {
jsx_parseElementAt(startPos: number, startLoc?: acorn.SourceLocation): acorn.Node;
jsx_parseText(): acorn.Node;
jsx_parseElement(): acorn.Node;
- }
}
-export = jsx;
+export interface JsxFunctionProperties {
+ tokTypes: JsxTokTypes;
+}
+
+export type JsxFunctionSignature = (options?: Options) => (BaseParser: typeof acorn.Parser) => AcornJsxParserCtor
+
+export type JsxFunction = JsxFunctionSignature & JsxFunctionProperties;
+
+declare const jsx: JsxFunction;
+
+export default jsx;
diff --git a/index.js b/index.js
index 004e080..b4d3212 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,5 @@
-'use strict';
-
-const XHTMLEntities = require('./xhtml');
+import * as acorn from "acorn";
+import XHTMLEntities from './xhtml.js';
const hexNumber = /^[\da-fA-F]+$/;
const decimalNumber = /^\d+$/;
@@ -70,7 +69,7 @@ function getQualifiedJSXName(object) {
getQualifiedJSXName(object.property);
}
-module.exports = function(options) {
+function acornJsx(options) {
options = options || {};
return function(Parser) {
return plugin({
@@ -82,26 +81,29 @@ module.exports = function(options) {
// This is `tokTypes` of the peer dep.
// This can be different instances from the actual `tokTypes` this plugin uses.
-Object.defineProperty(module.exports, "tokTypes", {
+Object.defineProperty(acornJsx, "tokTypes", {
get: function get_tokTypes() {
- return getJsxTokens(require("acorn")).tokTypes;
+ return getJsxTokens(acorn).tokTypes;
},
configurable: true,
enumerable: true
});
+
+export default acornJsx;
+
function plugin(options, Parser) {
- const acorn = Parser.acorn || require("acorn");
+ const acrn = Parser.acorn || acorn;
const acornJsx = getJsxTokens(acorn);
- const tt = acorn.tokTypes;
+ const tt = acrn.tokTypes;
const tok = acornJsx.tokTypes;
- const tokContexts = acorn.tokContexts;
+ const tokContexts = acrn.tokContexts;
const tc_oTag = acornJsx.tokContexts.tc_oTag;
const tc_cTag = acornJsx.tokContexts.tc_cTag;
const tc_expr = acornJsx.tokContexts.tc_expr;
- const isNewLine = acorn.isNewLine;
- const isIdentifierStart = acorn.isIdentifierStart;
- const isIdentifierChar = acorn.isIdentifierChar;
+ const isNewLine = acrn.isNewLine;
+ const isIdentifierStart = acrn.isIdentifierStart;
+ const isIdentifierChar = acrn.isIdentifierChar;
return class extends Parser {
// Expose actual `tokTypes` and `tokContexts` to other plugins.
diff --git a/package.json b/package.json
index 6debde9..c899924 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,16 @@
"description": "Modern, fast React.js JSX parser",
"homepage": "https://github.com/acornjs/acorn-jsx",
"version": "5.3.2",
+ "type": "module",
+ "main": "index.cjs",
+ "exports": {
+ "types": {
+ "import": "./index.d.ts",
+ "require": "./index.d.cts"
+ },
+ "import": "./index.js",
+ "require": "./index.cjs"
+ },
"maintainers": [
{
"name": "Ingvar Stepanyan",
@@ -16,12 +26,18 @@
},
"license": "MIT",
"scripts": {
- "test": "node test/run.js"
+ "attw": "attw --pack",
+ "test": "node test/run.js",
+ "build": "rollup -c",
+ "prepublishOnly": "npm run build"
},
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"devDependencies": {
- "acorn": "^8.0.1"
+ "@arethetypeswrong/cli": "^0.18.2",
+ "@rollup/plugin-commonjs": "^12.0.0",
+ "acorn": "^8.15.0",
+ "rollup": "^2.12.0"
}
}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..c1be435
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,10 @@
+export default {
+ input: "index.js",
+ external: ["acorn"],
+ output: {
+ file: "index.cjs",
+ exports: 'default',
+ format: "cjs",
+ banner: "// DO NOT edit this file, it's auto-generated from 'rollup.config.js'; any changes will be overwritten. \n"
+ }
+};
diff --git a/test/driver.js b/test/driver.js
index 3e152c1..a0b33f1 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -1,16 +1,16 @@
var tests = [];
-exports.test = function(code, ast, options, pluginOptions) {
+export function test(code, ast, options, pluginOptions) {
tests.push({code, ast, options, pluginOptions});
};
-exports.testFail = function(code, message, options, pluginOptions) {
+export function testFail(code, message, options, pluginOptions) {
tests.push({code, error: message, options, pluginOptions});
};
-exports.testAssert = function(code, assert, options) {
+export function testAssert(code, assert, options) {
tests.push({code, assert, options});
};
-exports.runTests = function(config, callback) {
+export function runTests(config, callback) {
var parse = config.parse;
for (var i = 0; i < tests.length; ++i) {
@@ -72,7 +72,7 @@ function addPath(str, pt) {
return str + " (" + pt + ")";
}
-var misMatch = exports.misMatch = function(exp, act) {
+var misMatch = function(exp, act) {
if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act);
} else if (exp instanceof RegExp || act instanceof RegExp) {
diff --git a/test/run.js b/test/run.js
index b9d98bf..e462920 100644
--- a/test/run.js
+++ b/test/run.js
@@ -1,6 +1,8 @@
-var driver = require("./driver.js");
-require("./tests-jsx.js");
-require("./tests-misc.js");
+import * as driver from "./driver.js";
+import "./tests-jsx.js";
+import "./tests-misc.js";
+import * as acorn from "acorn";
+import jsx from "../index.js";
function group(name) {
if (typeof console === "object" && console.group) {
@@ -18,7 +20,6 @@ function log(title, message) {
if (typeof console === "object") console.log(title, message);
}
-const acorn = require("acorn"), jsx = require("..")
const Parser = acorn.Parser.extend(jsx())
var stats, modes = {
diff --git a/test/tests-jsx.js b/test/tests-jsx.js
index b53549d..072b44d 100644
--- a/test/tests-jsx.js
+++ b/test/tests-jsx.js
@@ -20,6 +20,13 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import { test } from "./driver.js";
+import { testFail } from "./driver.js";
+import acornJsx from "../index.js";
+import { tokTypes as acornTokens } from "acorn";
+
+let jsxTokens = acornJsx.tokTypes;
+
var fbTestFixture = {
// Taken and adapted from esprima-fb/fbtest.js.
'JSX': {
@@ -3725,13 +3732,6 @@ var fbTestFixture = {
}
};
-if (typeof exports !== "undefined") {
- var test = require("./driver.js").test;
- var testFail = require("./driver.js").testFail;
- var jsxTokens = require("..").tokTypes;
- var acornTokens = require("acorn").tokTypes;
-}
-
testFail("var x = one
two
;", "Adjacent JSX elements must be wrapped in an enclosing tag (1:22)");
testFail("", "Unexpected token (1:4)");
diff --git a/test/tests-misc.js b/test/tests-misc.js
index 9ff0fa3..500d3df 100644
--- a/test/tests-misc.js
+++ b/test/tests-misc.js
@@ -1,11 +1,7 @@
-"use strict";
-
-if (typeof exports !== "undefined") {
- var assert = require("assert");
- var acorn = require("acorn");
- var jsx = require("..");
- var testAssert = require("./driver.js").testAssert;
-}
+import assert from "assert";
+import * as acorn from "acorn";
+import jsx from "../index.js";
+import { testAssert } from "./driver.js";
testAssert("// the enhanced Parser instance should have a static property 'acornJsx'.", function() {
const JsxParser = acorn.Parser.extend(jsx());
diff --git a/xhtml.js b/xhtml.js
index c152009..8f5aa79 100644
--- a/xhtml.js
+++ b/xhtml.js
@@ -1,4 +1,4 @@
-module.exports = {
+export default {
quot: '\u0022',
amp: '&',
apos: '\u0027',