Socket
Socket
Sign inDemoInstall

eslint-mdx

Package Overview
Dependencies
Maintainers
4
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-mdx - npm Package Compare versions

Comparing version 1.13.0 to 1.14.0

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [1.14.0](https://github.com/mdx-js/eslint-mdx/compare/v1.13.0...v1.14.0) (2021-07-11)
### Features
* bump all upgradable deps, fix related usage ([#321](https://github.com/mdx-js/eslint-mdx/issues/321)) ([ea49cac](https://github.com/mdx-js/eslint-mdx/commit/ea49cacaedf72fb0bcf61aa84c3c0ea5e58f9733))
# [1.13.0](https://github.com/mdx-js/eslint-mdx/compare/v1.12.0...v1.13.0) (2021-04-29)

@@ -8,0 +19,0 @@

899

lib/es2015.js

@@ -6,109 +6,95 @@ import path from 'path';

/// <reference path="../typings.d.ts" />
const FALLBACK_PARSERS = [
'@typescript-eslint/parser',
'@babel/eslint-parser',
'babel-eslint',
'espree',
"@typescript-eslint/parser",
"@babel/eslint-parser",
"babel-eslint",
"espree"
];
const JSX_TYPES = ['JSXElement', 'JSXFragment'];
const JSX_TYPES = ["JSXElement", "JSXFragment"];
const isJsxNode = (node) => JSX_TYPES.includes(node.type);
// eslint-disable-next-line sonarjs/cognitive-complexity
const normalizeParser = (parser) => {
if (parser) {
if (typeof parser === 'string') {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
parser = require(parser);
}
if (typeof parser === 'object') {
parser =
('parseForESLint' in parser && parser.parseForESLint) ||
('parse' in parser && parser.parse);
}
if (typeof parser !== 'function') {
throw new TypeError(`Invalid custom parser for \`eslint-mdx\`: ${parser}`);
}
return [parser];
if (parser) {
if (typeof parser === "string") {
parser = require(parser);
}
const parsers = [];
// try to load FALLBACK_PARSERS automatically
for (const fallback of FALLBACK_PARSERS) {
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const fallbackParser = require(fallback);
/* istanbul ignore next */
const parserFn = 'parseForESLint' in fallbackParser
? // eslint-disable-next-line @typescript-eslint/unbound-method
fallbackParser.parseForESLint
: // eslint-disable-next-line @typescript-eslint/unbound-method
fallbackParser.parse;
/* istanbul ignore else */
if (parserFn) {
parsers.push(parserFn);
}
}
catch (_a) { }
if (typeof parser === "object") {
parser = "parseForESLint" in parser && parser.parseForESLint || "parse" in parser && parser.parse;
}
return parsers;
if (typeof parser !== "function") {
throw new TypeError(`Invalid custom parser for \`eslint-mdx\`: ${parser}`);
}
return [parser];
}
const parsers = [];
for (const fallback of FALLBACK_PARSERS) {
try {
const fallbackParser = require(fallback);
const parserFn = "parseForESLint" in fallbackParser ? fallbackParser.parseForESLint : fallbackParser.parse;
if (parserFn) {
parsers.push(parserFn);
}
} catch (e) {
}
}
return parsers;
};
const normalizePosition = (loc) => {
const start = loc.start.offset;
const end = loc.end.offset;
return {
range: [start, end],
loc,
start,
end,
};
const start = loc.start.offset;
const end = loc.end.offset;
return {
range: [start, end],
loc,
start,
end
};
};
const hasProperties = (obj, properties) => typeof obj === 'object' &&
obj &&
properties.every(property => property in obj);
// fix #292
const hasProperties = (obj, properties) => typeof obj === "object" && obj && properties.every((property) => property in obj);
const getPositionAt = (code, offset) => {
let currOffset = 0;
const lines = code.split('\n');
// eslint-disable-next-line unicorn/no-for-loop
for (let index = 0; index < lines.length; index++) {
const line = index + 1;
const nextOffset = currOffset + lines[index].length;
if (nextOffset >= offset) {
return {
line,
column: offset - currOffset,
};
}
currOffset = nextOffset + 1; // add a line break `\n` offset
let currOffset = 0;
const lines = code.split("\n");
for (let index = 0; index < lines.length; index++) {
const line = index + 1;
const nextOffset = currOffset + lines[index].length;
if (nextOffset >= offset) {
return {
line,
column: offset - currOffset
};
}
currOffset = nextOffset + 1;
}
};
const restoreNodeLocation = (node, point) => {
if (node && typeof node === 'object') {
for (const value of Object.values(node)) {
restoreNodeLocation(value, point);
}
if (node && typeof node === "object") {
for (const value of Object.values(node)) {
restoreNodeLocation(value, point);
}
if (!hasProperties(node, ['loc', 'range'])) {
return node;
}
if (!hasProperties(node, ["loc", "range"])) {
return node;
}
let {
loc: { start: startLoc, end: endLoc },
range: [start, end]
} = node;
const range = [start += point.offset, end += point.offset];
return Object.assign(node, {
start,
end,
range,
loc: {
start: {
line: point.line + startLoc.line,
column: startLoc.column + (startLoc.line === 1 ? point.column : 0)
},
end: {
line: point.line + endLoc.line,
column: endLoc.column + (endLoc.line === 1 ? point.column : 0)
}
}
let { loc: { start: startLoc, end: endLoc }, range: [start, end], } = node;
const range = [(start += point.offset), (end += point.offset)];
return Object.assign(node, {
start,
end,
range,
loc: {
start: {
line: point.line + startLoc.line,
column: startLoc.column + (startLoc.line === 1 ? point.column : 0),
},
end: {
line: point.line + endLoc.line,
column: endLoc.column + (endLoc.line === 1 ? point.column : 0),
},
},
});
});
};
const arrayify = (...args) => args.reduce((arr, curr) => {
arr.push(...(Array.isArray(curr) ? curr : curr == null ? [] : [curr]));
return arr;
arr.push(...Array.isArray(curr) ? curr : curr == null ? [] : [curr]);
return arr;
}, []);

@@ -118,33 +104,24 @@ const first = (items) => items && items[0];

// based on https://github.com/mdx-js/mdx/blob/master/packages/remark-mdx/tag.js
const dotAllPolyfill = '[\0-\uFFFF]';
const attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
const unquoted = '[^"\'=<>`\\u0000-\\u0020]+';
const dotAllPolyfill = "[\0-\uFFFF]";
const attributeName = "[a-zA-Z_:][a-zA-Z0-9:._-]*";
const unquoted = "[^\"'=<>`\\u0000-\\u0020]+";
const singleQuoted = "'[^']*'";
const doubleQuoted = '"[^"]*"';
const jsProps = '{.*}'.replace('.', dotAllPolyfill);
const attributeValue = '(?:' +
unquoted +
'|' +
singleQuoted +
'|' +
doubleQuoted +
'|' +
jsProps +
')';
const attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)';
const openTag = '<[A-Za-z]*[A-Za-z0-9\\.\\-]*' + attribute + '*\\s*>';
const closeTag = '<\\s*\\/[A-Za-z]*[A-Za-z0-9\\.\\-]*\\s*>';
const selfClosingTag = '<[A-Za-z]*[A-Za-z0-9\\.\\-]*' + attribute + '*\\s*\\/?>';
const comment = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->';
const commentOpen = '(<!---*)';
const commentClose = '(-*-->)';
const jsProps = "{.*}".replace(".", dotAllPolyfill);
const attributeValue = "(?:" + unquoted + "|" + singleQuoted + "|" + doubleQuoted + "|" + jsProps + ")";
const attribute = "(?:\\s+" + attributeName + "(?:\\s*=\\s*" + attributeValue + ")?)";
const openTag = "<[A-Za-z]*[A-Za-z0-9\\.\\-]*" + attribute + "*\\s*>";
const closeTag = "<\\s*\\/[A-Za-z]*[A-Za-z0-9\\.\\-]*\\s*>";
const selfClosingTag = "<[A-Za-z]*[A-Za-z0-9\\.\\-]*" + attribute + "*\\s*\\/?>";
const comment = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->";
const commentOpen = "(<!---*)";
const commentClose = "(-*-->)";
const commentContent = `${commentOpen}([\\s\\S]*?)${commentClose}`;
const OPEN_TAG_REGEX = new RegExp(`^(?:${openTag})$`);
const CLOSE_TAG_REGEX = new RegExp(`^(?:${closeTag})$`);
const OPEN_CLOSE_TAG_REGEX = new RegExp(`^(?:${openTag + '[^<]*' + closeTag})$`);
const OPEN_CLOSE_TAG_REGEX = new RegExp(`^(?:${openTag + "[^<]*" + closeTag})$`);
const SELF_CLOSING_TAG_REGEX = new RegExp(`^(?:${selfClosingTag})$`);
const COMMENT_REGEX = new RegExp(`^(?:${comment})$`);
const COMMENT_CONTENT_REGEX = new RegExp(commentContent);
const COMMENT_CONTENT_REGEX_GLOBAL = new RegExp(commentContent, 'g');
const COMMENT_CONTENT_REGEX_GLOBAL = new RegExp(commentContent, "g");
const isOpenTag = (text) => OPEN_TAG_REGEX.test(text.trim());

@@ -156,380 +133,386 @@ const isCloseTag = (text) => CLOSE_TAG_REGEX.test(text.trim());

var __defProp$1 = Object.defineProperty;
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$1 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
if (__getOwnPropSymbols$1)
for (var prop of __getOwnPropSymbols$1(b)) {
if (__propIsEnum$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
}
return a;
};
class Traverse {
constructor({ code, enter }) {
this.code = code;
this._enter = enter;
constructor({ code, enter }) {
this.code = code;
this._enter = enter;
}
combineLeftJsxNodes(jsxNodes, parent) {
var _a;
const start = jsxNodes[0].position.start;
const end = __spreadValues$1({}, last(jsxNodes).position.end);
if (parent && ((_a = parent.position.indent) == null ? void 0 : _a.length) > 0) {
end.offset += parent.position.indent.reduce((acc, indent, index) => acc + (index ? indent + 1 : 0), 0);
}
combineLeftJsxNodes(jsxNodes, parent) {
var _a;
const start = jsxNodes[0].position.start;
const end = Object.assign({}, last(jsxNodes).position.end);
// fix #279
if (parent && ((_a = parent.position.indent) === null || _a === void 0 ? void 0 : _a.length) > 0) {
end.offset += parent.position.indent.reduce((acc, indent, index) => acc + (index ? indent + 1 : 0), 0);
}
return {
type: 'jsx',
data: jsxNodes[0].data,
value: this.code.slice(start.offset, end.offset),
position: {
start,
end,
},
};
}
// fix #7
combineJsxNodes(nodes, parent) {
let offset = 0;
let hasOpenTag = false;
const jsxNodes = [];
const { length } = nodes;
// eslint-disable-next-line sonarjs/cognitive-complexity
return nodes.reduce((acc, node, index) => {
if (node.type === 'jsx') {
const value = node.value;
if (isOpenTag(value)) {
offset++;
hasOpenTag = true;
jsxNodes.push(node);
}
else {
if (isCloseTag(value)) {
offset--;
jsxNodes.push(node);
}
else if (isComment(value) ||
isSelfClosingTag(value) ||
isOpenCloseTag(value)) {
jsxNodes.push(node);
}
else {
// #272, we consider the first jsx node as open tag although it's not precise
if (!index) {
offset++;
hasOpenTag = true;
}
try {
// fix #138
jsxNodes.push(...arrayify(parser.normalizeJsxNode(node, parent)));
}
catch (_a) {
// #272 related
/* istanbul ignore else */
if (offset) {
jsxNodes.push(node);
}
else {
// should never happen, just for robustness
const { start } = node.position;
throw Object.assign(new SyntaxError('unknown jsx node: ' + JSON.stringify(value)), {
lineNumber: start.line,
column: start.column,
index: start.offset,
});
}
}
}
if (!offset) {
// fix #158
const firstOpenTagIndex = jsxNodes.findIndex(node => typeof node.value === 'string' && isOpenTag(node.value));
if (firstOpenTagIndex === -1) {
if (hasOpenTag) {
acc.push(this.combineLeftJsxNodes(jsxNodes, parent));
}
else {
acc.push(...jsxNodes);
}
}
else {
acc.push(...jsxNodes.slice(0, firstOpenTagIndex), this.combineLeftJsxNodes(jsxNodes.slice(firstOpenTagIndex), parent));
}
jsxNodes.length = 0;
}
}
return {
type: "jsx",
data: jsxNodes[0].data,
value: this.code.slice(start.offset, end.offset),
position: {
start,
end
}
};
}
combineJsxNodes(nodes, parent) {
let offset = 0;
let hasOpenTag = false;
const jsxNodes = [];
const { length } = nodes;
return nodes.reduce((acc, node, index) => {
if (node.type === "jsx") {
const value = node.value;
if (isOpenTag(value)) {
offset++;
hasOpenTag = true;
jsxNodes.push(node);
} else {
if (isCloseTag(value)) {
offset--;
jsxNodes.push(node);
} else if (isComment(value) || isSelfClosingTag(value) || isOpenCloseTag(value)) {
jsxNodes.push(node);
} else {
if (!index) {
offset++;
hasOpenTag = true;
}
else if (offset) {
try {
jsxNodes.push(...arrayify(parser.normalizeJsxNode(node, parent)));
} catch (e) {
if (offset) {
jsxNodes.push(node);
} else {
const { start } = node.position;
throw Object.assign(new SyntaxError("unknown jsx node: " + JSON.stringify(value)), {
lineNumber: start.line,
column: start.column,
index: start.offset
});
}
}
else {
acc.push(node);
}
if (index === length - 1 && jsxNodes.length > 0) {
}
if (!offset) {
const firstOpenTagIndex = jsxNodes.findIndex((node2) => typeof node2.value === "string" && isOpenTag(node2.value));
if (firstOpenTagIndex === -1) {
if (hasOpenTag) {
acc.push(this.combineLeftJsxNodes(jsxNodes, parent));
} else {
acc.push(...jsxNodes);
}
} else {
acc.push(...jsxNodes.slice(0, firstOpenTagIndex), this.combineLeftJsxNodes(jsxNodes.slice(firstOpenTagIndex), parent));
}
return acc;
}, []);
}
traverse(node, parent) {
/* istanbul ignore if */
if (!node) {
// should never happen, just for robustness
return;
jsxNodes.length = 0;
}
}
let children = node.children;
if (children) {
const parent = node;
children = node.children = this.combineJsxNodes(children, parent);
for (const child of children) {
this.traverse(child, parent);
}
}
this._enter(node, parent);
} else if (offset) {
jsxNodes.push(node);
} else {
acc.push(node);
}
if (index === length - 1 && jsxNodes.length > 0) {
acc.push(this.combineLeftJsxNodes(jsxNodes, parent));
}
return acc;
}, []);
}
traverse(node, parent) {
if (!node) {
return;
}
if ("children" in node) {
const parent2 = node;
parent2.children = this.combineJsxNodes(parent2.children, parent2);
for (const child of parent2.children) {
this.traverse(child, parent2);
}
}
this._enter(node, parent);
}
}
const traverse = (root, options) => new Traverse(options).traverse(root);
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const mdProcessor = unified().use(remarkParse).freeze();
const mdxProcessor = mdProcessor().use(remarkMdx).freeze();
const AST_PROPS = ['body', 'comments', 'tokens'];
const ES_NODE_TYPES = ['export', 'import', 'jsx'];
const LOC_ERROR_PROPERTIES = ['column', 'lineNumber'];
const DEFAULT_EXTENSIONS = ['.mdx'];
const MARKDOWN_EXTENSIONS = ['.md'];
const AST_PROPS = ["body", "comments", "tokens"];
const ES_NODE_TYPES = ["export", "import", "jsx"];
const LOC_ERROR_PROPERTIES = ["column", "lineNumber"];
const DEFAULT_EXTENSIONS = [".mdx"];
const MARKDOWN_EXTENSIONS = [".md"];
const DEFAULT_PARSER_OPTIONS = {
comment: true,
ecmaFeatures: {
jsx: true,
},
ecmaVersion: new Date().getUTCFullYear(),
sourceType: 'module',
tokens: true,
filePath: '__placeholder__.mdx',
// required for @typescript-eslint/parser
// reference: https://github.com/typescript-eslint/typescript-eslint/pull/2028
loc: true,
range: true,
comment: true,
ecmaFeatures: {
jsx: true
},
ecmaVersion: new Date().getUTCFullYear(),
sourceType: "module",
tokens: true,
filePath: "__placeholder__.mdx",
loc: true,
range: true
};
const JSX_WRAPPER_START = '<$>';
const JSX_WRAPPER_END = '</$>';
const JSX_WRAPPER_START = "<$>";
const JSX_WRAPPER_END = "</$>";
const OFFSET = JSX_WRAPPER_START.length;
class Parser {
constructor() {
// @internal
this._options = DEFAULT_PARSER_OPTIONS;
this.parse = this.parse.bind(this);
this.parseForESLint = this.parseForESLint.bind(this);
constructor() {
this._options = DEFAULT_PARSER_OPTIONS;
this.parse = this.parse.bind(this);
this.parseForESLint = this.parseForESLint.bind(this);
}
normalizeJsxNode(node, parent, options = this._options) {
const value = node.value;
if (node.type !== "jsx" || isComment(value)) {
return node;
}
normalizeJsxNode(node, parent, options = this._options) {
const value = node.value;
if (node.type !== 'jsx' || isComment(value)) {
return node;
}
const commentContent = COMMENT_CONTENT_REGEX.exec(value);
if (commentContent) {
const comments = [];
const { position: { start: { line, column, offset: startOffset }, }, data, } = node;
Object.assign(node, {
data: Object.assign(Object.assign({}, data), { jsxType: 'JSXElementWithHTMLComments', comments,
// jsx in paragraph is considered as plain html in mdx, what means html style comments are valid
// TODO: in this case, jsx style comments could be a mistake
inline: !!parent && parent.type !== 'root' }),
value: value.replace(COMMENT_CONTENT_REGEX_GLOBAL, (matched, $0, $1, $2, offset) => {
const endOffset = offset + matched.length;
const startLines = value.slice(0, offset).split('\n');
const endLines = value.slice(0, endOffset).split('\n');
const fixed = `{/${'*'.repeat($0.length - 2)}${$1}${'*'.repeat($2.length - 2)}/}`;
const startLineOffset = startLines.length - 1;
const endLineOffset = endLines.length - 1;
comments.push({
fixed,
// ! eslint ast column is 0-indexed, but unified is 1-indexed
loc: {
start: {
line: line + startLineOffset,
column: last(startLines).length +
(startLineOffset ? 0 : column - 1),
offset: startOffset + offset,
},
end: {
line: line + endLineOffset,
column: last(endLines).length + (endLineOffset ? 0 : column - 1),
offset: startOffset + endOffset,
},
},
origin: matched,
});
return fixed;
}),
});
}
return this._normalizeJsxNodes(node, options);
const commentContent = COMMENT_CONTENT_REGEX.exec(value);
if (commentContent) {
const comments = [];
const {
position: {
start: { line, column, offset: startOffset }
},
data
} = node;
Object.assign(node, {
data: __spreadProps(__spreadValues({}, data), {
jsxType: "JSXElementWithHTMLComments",
comments,
inline: !!parent && parent.type !== "root"
}),
value: value.replace(COMMENT_CONTENT_REGEX_GLOBAL, (matched, $0, $1, $2, offset) => {
const endOffset = offset + matched.length;
const startLines = value.slice(0, offset).split("\n");
const endLines = value.slice(0, endOffset).split("\n");
const fixed = `{/${"*".repeat($0.length - 2)}${$1}${"*".repeat($2.length - 2)}/}`;
const startLineOffset = startLines.length - 1;
const endLineOffset = endLines.length - 1;
comments.push({
fixed,
loc: {
start: {
line: line + startLineOffset,
column: last(startLines).length + (startLineOffset ? 0 : column - 1),
offset: startOffset + offset
},
end: {
line: line + endLineOffset,
column: last(endLines).length + (endLineOffset ? 0 : column - 1),
offset: startOffset + endOffset
}
},
origin: matched
});
return fixed;
})
});
}
parse(code, options) {
return this.parseForESLint(code, options).ast;
return this._normalizeJsxNodes(node, options);
}
parse(code, options) {
return this.parseForESLint(code, options).ast;
}
parseForESLint(code, options) {
const extname = path.extname(options.filePath);
const isMdx = DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(extname);
const isMarkdown = MARKDOWN_EXTENSIONS.concat(options.markdownExtensions || []).includes(extname);
if (!isMdx && !isMarkdown) {
return this._eslintParse(code, options);
}
parseForESLint(code, options) {
const extname = path.extname(options.filePath);
const isMdx = DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(extname);
const isMarkdown = MARKDOWN_EXTENSIONS.concat(options.markdownExtensions || []).includes(extname);
if (!isMdx && !isMarkdown) {
return this._eslintParse(code, options);
const root = (isMdx ? mdxProcessor : mdProcessor).parse(code);
this._ast = __spreadProps(__spreadValues({}, normalizePosition(root.position)), {
type: "Program",
sourceType: options.sourceType || "module",
body: [],
comments: [],
tokens: []
});
this._services = {
JSXElementsWithHTMLComments: []
};
if (isMdx) {
traverse(root, {
code,
enter: (node, parent) => {
if (!ES_NODE_TYPES.includes(node.type)) {
return;
}
for (const normalizedNode of arrayify(this.normalizeJsxNode(node, parent, options))) {
this._nodeToAst(code, normalizedNode, options);
}
}
const root = (isMdx ? mdxProcessor : mdProcessor).parse(code);
this._ast = Object.assign(Object.assign({}, normalizePosition(root.position)), { type: 'Program', sourceType: options.sourceType || 'module', body: [], comments: [], tokens: [] });
this._services = {
JSXElementsWithHTMLComments: [],
};
if (isMdx) {
traverse(root, {
code,
enter: (node, parent) => {
if (!ES_NODE_TYPES.includes(node.type)) {
return;
}
for (const normalizedNode of arrayify(this.normalizeJsxNode(node, parent, options))) {
this._nodeToAst(code, normalizedNode, options);
}
},
});
}
return {
ast: this._ast,
services: this._services,
};
});
}
// @internal
_eslintParse(code, options) {
if (!this._parsers || options.parser !== this._options.parser) {
this._parsers = normalizeParser(options.parser);
return {
ast: this._ast,
services: this._services
};
}
_eslintParse(code, options) {
if (!this._parsers || options.parser !== this._options.parser) {
this._parsers = normalizeParser(options.parser);
}
if (options.filePath && this._options !== options) {
Object.assign(this._options, options);
}
let program;
let parseError;
for (const parser2 of this._parsers) {
try {
program = parser2(code, this._options);
break;
} catch (err) {
if (!parseError) {
parseError = err;
}
/* istanbul ignore else */
if (options.filePath && this._options !== options) {
Object.assign(this._options, options);
}
let program;
let parseError;
for (const parser of this._parsers) {
try {
program = parser(code, this._options);
break;
}
catch (err) {
if (!parseError) {
parseError = err;
}
}
}
if (!program && parseError) {
throw parseError;
}
/* istanbul ignore next */
return ('ast' in program && program.ast
? program
: { ast: program });
}
}
// fix adjacent JSX nodes
// @internal
// eslint-disable-next-line sonarjs/cognitive-complexity
_normalizeJsxNodes(node, options) {
const value = node.value;
let program;
try {
// wrap into single element which is valid jsx but not valid jsx in mdx, so that it won't break on adjacent JSX nodes
program = this._eslintParse(`${JSX_WRAPPER_START}${value}${JSX_WRAPPER_END}`, options).ast;
if (!program && parseError) {
throw parseError;
}
return "ast" in program && program.ast ? program : { ast: program };
}
_normalizeJsxNodes(node, options) {
const value = node.value;
let program;
try {
program = this._eslintParse(`${JSX_WRAPPER_START}${value}${JSX_WRAPPER_END}`, options).ast;
} catch (err) {
if (hasProperties(err, LOC_ERROR_PROPERTIES)) {
const {
position: { start }
} = node;
if ("index" in err) {
err.index += start.offset - OFFSET;
} else if ("pos" in err) {
err.pos += start.offset - OFFSET;
}
catch (err) {
if (hasProperties(err, LOC_ERROR_PROPERTIES)) {
const { position: { start }, } = node;
/* istanbul ignore else */
if ('index' in err) {
err.index += start.offset - OFFSET;
}
else if ('pos' in err) {
err.pos += start.offset - OFFSET;
}
err.column =
/* istanbul ignore next */
err.lineNumber > 1 ? err.column : err.column + start.column - OFFSET;
err.lineNumber += start.line - 1;
throw err;
}
return node;
}
const { expression } = program.body[0];
if (!isJsxNode(expression) || expression.children.length <= 1) {
return node;
}
const { position: { start: { line, offset }, }, data, } = node;
return expression.children.reduce((nodes, jsNode) => {
if (!isJsxNode(jsNode)) {
return nodes;
}
/* istanbul ignore next */
const { start: nodeStart, end: nodeEnd, loc: { start, end } = {
start: { column: nodeStart, line: 1 },
end: { column: nodeEnd, line: 1 },
}, range = [nodeStart, nodeEnd], } = jsNode;
const startLine = line + start.line - 1;
const endLine = line + end.line - 1;
const startOffset = range[0] - OFFSET;
const endOffset = range[1] - OFFSET;
nodes.push({
type: 'jsx',
data: nodes.length > 0 ? null : data,
value: value.slice(startOffset, endOffset),
position: {
start: {
line: startLine,
column: line === startLine ? start.column - OFFSET : start.column,
offset: offset + startOffset,
},
end: {
line: endLine,
column: line === startLine ? end.column - OFFSET : end.column,
offset: offset + endOffset,
},
},
});
return nodes;
}, []);
err.column = err.lineNumber > 1 ? err.column : err.column + start.column - OFFSET;
err.lineNumber += start.line - 1;
throw err;
}
return node;
}
// @internal
_nodeToAst(code, node, options) {
if (node.data && node.data.jsxType === 'JSXElementWithHTMLComments') {
this._services.JSXElementsWithHTMLComments.push(node);
const { expression } = program.body[0];
if (!isJsxNode(expression) || expression.children.length <= 1) {
return node;
}
const {
position: {
start: { line, offset }
},
data
} = node;
return expression.children.reduce((nodes, jsNode) => {
if (!isJsxNode(jsNode)) {
return nodes;
}
const {
start: nodeStart,
end: nodeEnd,
loc: { start, end } = {
start: { column: nodeStart, line: 1 },
end: { column: nodeEnd, line: 1 }
},
range = [nodeStart, nodeEnd]
} = jsNode;
const startLine = line + start.line - 1;
const endLine = line + end.line - 1;
const startOffset = range[0] - OFFSET;
const endOffset = range[1] - OFFSET;
nodes.push({
type: "jsx",
data: nodes.length > 0 ? null : data,
value: value.slice(startOffset, endOffset),
position: {
start: {
line: startLine,
column: line === startLine ? start.column - OFFSET : start.column,
offset: offset + startOffset
},
end: {
line: endLine,
column: line === startLine ? end.column - OFFSET : end.column,
offset: offset + endOffset
}
}
const value = node.value;
const { loc, start, end } = normalizePosition(node.position);
// fix #4
if (isComment(value)) {
const comment = COMMENT_CONTENT_REGEX.exec(value)[2];
this._ast.comments.push({
type: 'Block',
value: comment,
loc,
range: [start, end],
});
return;
}
const startLine = loc.start.line - 1; // ! line is 1-indexed, change to 0-indexed to simplify usage
let program;
try {
program = this._eslintParse(value, options).ast;
}
catch (e) {
/* istanbul ignore if */
if (hasProperties(e, LOC_ERROR_PROPERTIES)) {
// should be handled by `_normalizeJsxNodes`, just for robustness
e.index += start;
e.column = e.lineNumber > 1 ? e.column : e.column + loc.start.column;
e.lineNumber += startLine;
}
throw e;
}
const startPoint = {
line: startLine,
// #279 related
column: getPositionAt(code, start).column,
offset: start,
};
for (const prop of AST_PROPS)
this._ast[prop].push(
// ts doesn't understand the mixed type
...program[prop].map((item) => restoreNodeLocation(item, startPoint)));
});
return nodes;
}, []);
}
_nodeToAst(code, node, options) {
if (node.data && node.data.jsxType === "JSXElementWithHTMLComments") {
this._services.JSXElementsWithHTMLComments.push(node);
}
const value = node.value;
const { loc, start, end } = normalizePosition(node.position);
if (isComment(value)) {
const comment = COMMENT_CONTENT_REGEX.exec(value)[2];
this._ast.comments.push({
type: "Block",
value: comment,
loc,
range: [start, end]
});
return;
}
const startLine = loc.start.line - 1;
let program;
try {
program = this._eslintParse(value, options).ast;
} catch (e) {
if (hasProperties(e, LOC_ERROR_PROPERTIES)) {
e.index += start;
e.column = e.lineNumber > 1 ? e.column : e.column + loc.start.column;
e.lineNumber += startLine;
}
throw e;
}
const startPoint = {
line: startLine,
column: getPositionAt(code, start).column,
offset: start
};
for (const prop of AST_PROPS)
this._ast[prop].push(...program[prop].map((item) => restoreNodeLocation(item, startPoint)));
}
}
const parser = new Parser();
// eslint-disable-next-line @typescript-eslint/unbound-method
const { parse, parseForESLint } = parser;
export { AST_PROPS, CLOSE_TAG_REGEX, COMMENT_CONTENT_REGEX, COMMENT_CONTENT_REGEX_GLOBAL, COMMENT_REGEX, DEFAULT_EXTENSIONS, DEFAULT_PARSER_OPTIONS, ES_NODE_TYPES, FALLBACK_PARSERS, JSX_TYPES, LOC_ERROR_PROPERTIES, MARKDOWN_EXTENSIONS, OPEN_CLOSE_TAG_REGEX, OPEN_TAG_REGEX, Parser, SELF_CLOSING_TAG_REGEX, Traverse, arrayify, closeTag, comment, commentClose, commentContent, commentOpen, first, getPositionAt, hasProperties, isCloseTag, isComment, isJsxNode, isOpenCloseTag, isOpenTag, isSelfClosingTag, last, mdProcessor, mdxProcessor, normalizeParser, normalizePosition, openTag, parse, parseForESLint, parser, restoreNodeLocation, selfClosingTag, traverse };

@@ -1,2 +0,1 @@

import { __assign, __spreadArray } from 'tslib';
import path from 'path';

@@ -7,560 +6,511 @@ import remarkMdx from 'remark-mdx';

/// <reference path="../typings.d.ts" />
var FALLBACK_PARSERS = [
'@typescript-eslint/parser',
'@babel/eslint-parser',
'babel-eslint',
'espree',
const FALLBACK_PARSERS = [
"@typescript-eslint/parser",
"@babel/eslint-parser",
"babel-eslint",
"espree"
];
var JSX_TYPES = ['JSXElement', 'JSXFragment'];
var isJsxNode = function (node) {
return JSX_TYPES.includes(node.type);
};
// eslint-disable-next-line sonarjs/cognitive-complexity
var normalizeParser = function (parser) {
if (parser) {
if (typeof parser === 'string') {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
parser = require(parser);
}
if (typeof parser === 'object') {
parser =
('parseForESLint' in parser && parser.parseForESLint) ||
('parse' in parser && parser.parse);
}
if (typeof parser !== 'function') {
throw new TypeError("Invalid custom parser for `eslint-mdx`: " + parser);
}
return [parser];
const JSX_TYPES = ["JSXElement", "JSXFragment"];
const isJsxNode = (node) => JSX_TYPES.includes(node.type);
const normalizeParser = (parser) => {
if (parser) {
if (typeof parser === "string") {
parser = require(parser);
}
var parsers = [];
// try to load FALLBACK_PARSERS automatically
for (var _i = 0, FALLBACK_PARSERS_1 = FALLBACK_PARSERS; _i < FALLBACK_PARSERS_1.length; _i++) {
var fallback = FALLBACK_PARSERS_1[_i];
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
var fallbackParser = require(fallback);
/* istanbul ignore next */
var parserFn = 'parseForESLint' in fallbackParser
? // eslint-disable-next-line @typescript-eslint/unbound-method
fallbackParser.parseForESLint
: // eslint-disable-next-line @typescript-eslint/unbound-method
fallbackParser.parse;
/* istanbul ignore else */
if (parserFn) {
parsers.push(parserFn);
}
}
catch (_a) { }
if (typeof parser === "object") {
parser = "parseForESLint" in parser && parser.parseForESLint || "parse" in parser && parser.parse;
}
return parsers;
if (typeof parser !== "function") {
throw new TypeError(`Invalid custom parser for \`eslint-mdx\`: ${parser}`);
}
return [parser];
}
const parsers = [];
for (const fallback of FALLBACK_PARSERS) {
try {
const fallbackParser = require(fallback);
const parserFn = "parseForESLint" in fallbackParser ? fallbackParser.parseForESLint : fallbackParser.parse;
if (parserFn) {
parsers.push(parserFn);
}
} catch (e) {
}
}
return parsers;
};
var normalizePosition = function (loc) {
var start = loc.start.offset;
var end = loc.end.offset;
return {
range: [start, end],
loc: loc,
start: start,
end: end,
};
const normalizePosition = (loc) => {
const start = loc.start.offset;
const end = loc.end.offset;
return {
range: [start, end],
loc,
start,
end
};
};
var hasProperties = function (obj, properties) {
return typeof obj === 'object' &&
obj &&
properties.every(function (property) { return property in obj; });
};
// fix #292
var getPositionAt = function (code, offset) {
var currOffset = 0;
var lines = code.split('\n');
// eslint-disable-next-line unicorn/no-for-loop
for (var index = 0; index < lines.length; index++) {
var line = index + 1;
var nextOffset = currOffset + lines[index].length;
if (nextOffset >= offset) {
return {
line: line,
column: offset - currOffset,
};
}
currOffset = nextOffset + 1; // add a line break `\n` offset
const hasProperties = (obj, properties) => typeof obj === "object" && obj && properties.every((property) => property in obj);
const getPositionAt = (code, offset) => {
let currOffset = 0;
const lines = code.split("\n");
for (let index = 0; index < lines.length; index++) {
const line = index + 1;
const nextOffset = currOffset + lines[index].length;
if (nextOffset >= offset) {
return {
line,
column: offset - currOffset
};
}
currOffset = nextOffset + 1;
}
};
var restoreNodeLocation = function (node, point) {
if (node && typeof node === 'object') {
for (var _i = 0, _a = Object.values(node); _i < _a.length; _i++) {
var value = _a[_i];
restoreNodeLocation(value, point);
}
const restoreNodeLocation = (node, point) => {
if (node && typeof node === "object") {
for (const value of Object.values(node)) {
restoreNodeLocation(value, point);
}
if (!hasProperties(node, ['loc', 'range'])) {
return node;
}
if (!hasProperties(node, ["loc", "range"])) {
return node;
}
let {
loc: { start: startLoc, end: endLoc },
range: [start, end]
} = node;
const range = [start += point.offset, end += point.offset];
return Object.assign(node, {
start,
end,
range,
loc: {
start: {
line: point.line + startLoc.line,
column: startLoc.column + (startLoc.line === 1 ? point.column : 0)
},
end: {
line: point.line + endLoc.line,
column: endLoc.column + (endLoc.line === 1 ? point.column : 0)
}
}
var _b = node.loc, startLoc = _b.start, endLoc = _b.end, _c = node.range, start = _c[0], end = _c[1];
var range = [(start += point.offset), (end += point.offset)];
return Object.assign(node, {
start: start,
end: end,
range: range,
loc: {
start: {
line: point.line + startLoc.line,
column: startLoc.column + (startLoc.line === 1 ? point.column : 0),
},
end: {
line: point.line + endLoc.line,
column: endLoc.column + (endLoc.line === 1 ? point.column : 0),
},
},
});
});
};
var arrayify = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return args.reduce(function (arr, curr) {
arr.push.apply(arr, (Array.isArray(curr) ? curr : curr == null ? [] : [curr]));
return arr;
}, []);
};
var first = function (items) { return items && items[0]; };
var last = function (items) {
return items && items[items.length - 1];
};
const arrayify = (...args) => args.reduce((arr, curr) => {
arr.push(...Array.isArray(curr) ? curr : curr == null ? [] : [curr]);
return arr;
}, []);
const first = (items) => items && items[0];
const last = (items) => items && items[items.length - 1];
// based on https://github.com/mdx-js/mdx/blob/master/packages/remark-mdx/tag.js
var dotAllPolyfill = '[\0-\uFFFF]';
var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
var unquoted = '[^"\'=<>`\\u0000-\\u0020]+';
var singleQuoted = "'[^']*'";
var doubleQuoted = '"[^"]*"';
var jsProps = '{.*}'.replace('.', dotAllPolyfill);
var attributeValue = '(?:' +
unquoted +
'|' +
singleQuoted +
'|' +
doubleQuoted +
'|' +
jsProps +
')';
var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)';
var openTag = '<[A-Za-z]*[A-Za-z0-9\\.\\-]*' + attribute + '*\\s*>';
var closeTag = '<\\s*\\/[A-Za-z]*[A-Za-z0-9\\.\\-]*\\s*>';
var selfClosingTag = '<[A-Za-z]*[A-Za-z0-9\\.\\-]*' + attribute + '*\\s*\\/?>';
var comment = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->';
var commentOpen = '(<!---*)';
var commentClose = '(-*-->)';
var commentContent = commentOpen + "([\\s\\S]*?)" + commentClose;
var OPEN_TAG_REGEX = new RegExp("^(?:" + openTag + ")$");
var CLOSE_TAG_REGEX = new RegExp("^(?:" + closeTag + ")$");
var OPEN_CLOSE_TAG_REGEX = new RegExp("^(?:" + (openTag + '[^<]*' + closeTag) + ")$");
var SELF_CLOSING_TAG_REGEX = new RegExp("^(?:" + selfClosingTag + ")$");
var COMMENT_REGEX = new RegExp("^(?:" + comment + ")$");
var COMMENT_CONTENT_REGEX = new RegExp(commentContent);
var COMMENT_CONTENT_REGEX_GLOBAL = new RegExp(commentContent, 'g');
var isOpenTag = function (text) { return OPEN_TAG_REGEX.test(text.trim()); };
var isCloseTag = function (text) { return CLOSE_TAG_REGEX.test(text.trim()); };
var isComment = function (text) { return COMMENT_REGEX.test(text.trim()); };
var isOpenCloseTag = function (text) {
return OPEN_CLOSE_TAG_REGEX.test(text.trim());
};
var isSelfClosingTag = function (text) {
return SELF_CLOSING_TAG_REGEX.test(text.trim());
};
const dotAllPolyfill = "[\0-\uFFFF]";
const attributeName = "[a-zA-Z_:][a-zA-Z0-9:._-]*";
const unquoted = "[^\"'=<>`\\u0000-\\u0020]+";
const singleQuoted = "'[^']*'";
const doubleQuoted = '"[^"]*"';
const jsProps = "{.*}".replace(".", dotAllPolyfill);
const attributeValue = "(?:" + unquoted + "|" + singleQuoted + "|" + doubleQuoted + "|" + jsProps + ")";
const attribute = "(?:\\s+" + attributeName + "(?:\\s*=\\s*" + attributeValue + ")?)";
const openTag = "<[A-Za-z]*[A-Za-z0-9\\.\\-]*" + attribute + "*\\s*>";
const closeTag = "<\\s*\\/[A-Za-z]*[A-Za-z0-9\\.\\-]*\\s*>";
const selfClosingTag = "<[A-Za-z]*[A-Za-z0-9\\.\\-]*" + attribute + "*\\s*\\/?>";
const comment = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->";
const commentOpen = "(<!---*)";
const commentClose = "(-*-->)";
const commentContent = `${commentOpen}([\\s\\S]*?)${commentClose}`;
const OPEN_TAG_REGEX = new RegExp(`^(?:${openTag})$`);
const CLOSE_TAG_REGEX = new RegExp(`^(?:${closeTag})$`);
const OPEN_CLOSE_TAG_REGEX = new RegExp(`^(?:${openTag + "[^<]*" + closeTag})$`);
const SELF_CLOSING_TAG_REGEX = new RegExp(`^(?:${selfClosingTag})$`);
const COMMENT_REGEX = new RegExp(`^(?:${comment})$`);
const COMMENT_CONTENT_REGEX = new RegExp(commentContent);
const COMMENT_CONTENT_REGEX_GLOBAL = new RegExp(commentContent, "g");
const isOpenTag = (text) => OPEN_TAG_REGEX.test(text.trim());
const isCloseTag = (text) => CLOSE_TAG_REGEX.test(text.trim());
const isComment = (text) => COMMENT_REGEX.test(text.trim());
const isOpenCloseTag = (text) => OPEN_CLOSE_TAG_REGEX.test(text.trim());
const isSelfClosingTag = (text) => SELF_CLOSING_TAG_REGEX.test(text.trim());
var Traverse = /** @class */ (function () {
function Traverse(_a) {
var code = _a.code, enter = _a.enter;
this.code = code;
this._enter = enter;
var __defProp$1 = Object.defineProperty;
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$1 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
if (__getOwnPropSymbols$1)
for (var prop of __getOwnPropSymbols$1(b)) {
if (__propIsEnum$1.call(b, prop))
__defNormalProp$1(a, prop, b[prop]);
}
Traverse.prototype.combineLeftJsxNodes = function (jsxNodes, parent) {
var _a;
var start = jsxNodes[0].position.start;
var end = __assign({}, last(jsxNodes).position.end);
// fix #279
if (parent && ((_a = parent.position.indent) === null || _a === void 0 ? void 0 : _a.length) > 0) {
end.offset += parent.position.indent.reduce(function (acc, indent, index) { return acc + (index ? indent + 1 : 0); }, 0);
}
return {
type: 'jsx',
data: jsxNodes[0].data,
value: this.code.slice(start.offset, end.offset),
position: {
start: start,
end: end,
},
};
return a;
};
class Traverse {
constructor({ code, enter }) {
this.code = code;
this._enter = enter;
}
combineLeftJsxNodes(jsxNodes, parent) {
var _a;
const start = jsxNodes[0].position.start;
const end = __spreadValues$1({}, last(jsxNodes).position.end);
if (parent && ((_a = parent.position.indent) == null ? void 0 : _a.length) > 0) {
end.offset += parent.position.indent.reduce((acc, indent, index) => acc + (index ? indent + 1 : 0), 0);
}
return {
type: "jsx",
data: jsxNodes[0].data,
value: this.code.slice(start.offset, end.offset),
position: {
start,
end
}
};
// fix #7
Traverse.prototype.combineJsxNodes = function (nodes, parent) {
var _this = this;
var offset = 0;
var hasOpenTag = false;
var jsxNodes = [];
var length = nodes.length;
// eslint-disable-next-line sonarjs/cognitive-complexity
return nodes.reduce(function (acc, node, index) {
if (node.type === 'jsx') {
var value = node.value;
if (isOpenTag(value)) {
offset++;
hasOpenTag = true;
jsxNodes.push(node);
}
else {
if (isCloseTag(value)) {
offset--;
jsxNodes.push(node);
}
else if (isComment(value) ||
isSelfClosingTag(value) ||
isOpenCloseTag(value)) {
jsxNodes.push(node);
}
else {
// #272, we consider the first jsx node as open tag although it's not precise
if (!index) {
offset++;
hasOpenTag = true;
}
try {
// fix #138
jsxNodes.push.apply(jsxNodes, arrayify(parser.normalizeJsxNode(node, parent)));
}
catch (_a) {
// #272 related
/* istanbul ignore else */
if (offset) {
jsxNodes.push(node);
}
else {
// should never happen, just for robustness
var start = node.position.start;
throw Object.assign(new SyntaxError('unknown jsx node: ' + JSON.stringify(value)), {
lineNumber: start.line,
column: start.column,
index: start.offset,
});
}
}
}
if (!offset) {
// fix #158
var firstOpenTagIndex = jsxNodes.findIndex(function (node) { return typeof node.value === 'string' && isOpenTag(node.value); });
if (firstOpenTagIndex === -1) {
if (hasOpenTag) {
acc.push(_this.combineLeftJsxNodes(jsxNodes, parent));
}
else {
acc.push.apply(acc, jsxNodes);
}
}
else {
acc.push.apply(acc, __spreadArray(__spreadArray([], jsxNodes.slice(0, firstOpenTagIndex)), [_this.combineLeftJsxNodes(jsxNodes.slice(firstOpenTagIndex), parent)]));
}
jsxNodes.length = 0;
}
}
}
combineJsxNodes(nodes, parent) {
let offset = 0;
let hasOpenTag = false;
const jsxNodes = [];
const { length } = nodes;
return nodes.reduce((acc, node, index) => {
if (node.type === "jsx") {
const value = node.value;
if (isOpenTag(value)) {
offset++;
hasOpenTag = true;
jsxNodes.push(node);
} else {
if (isCloseTag(value)) {
offset--;
jsxNodes.push(node);
} else if (isComment(value) || isSelfClosingTag(value) || isOpenCloseTag(value)) {
jsxNodes.push(node);
} else {
if (!index) {
offset++;
hasOpenTag = true;
}
else if (offset) {
try {
jsxNodes.push(...arrayify(parser.normalizeJsxNode(node, parent)));
} catch (e) {
if (offset) {
jsxNodes.push(node);
} else {
const { start } = node.position;
throw Object.assign(new SyntaxError("unknown jsx node: " + JSON.stringify(value)), {
lineNumber: start.line,
column: start.column,
index: start.offset
});
}
}
else {
acc.push(node);
}
if (!offset) {
const firstOpenTagIndex = jsxNodes.findIndex((node2) => typeof node2.value === "string" && isOpenTag(node2.value));
if (firstOpenTagIndex === -1) {
if (hasOpenTag) {
acc.push(this.combineLeftJsxNodes(jsxNodes, parent));
} else {
acc.push(...jsxNodes);
}
} else {
acc.push(...jsxNodes.slice(0, firstOpenTagIndex), this.combineLeftJsxNodes(jsxNodes.slice(firstOpenTagIndex), parent));
}
if (index === length - 1 && jsxNodes.length > 0) {
acc.push(_this.combineLeftJsxNodes(jsxNodes, parent));
}
return acc;
}, []);
};
Traverse.prototype.traverse = function (node, parent) {
/* istanbul ignore if */
if (!node) {
// should never happen, just for robustness
return;
jsxNodes.length = 0;
}
}
var children = node.children;
if (children) {
var parent_1 = node;
children = node.children = this.combineJsxNodes(children, parent_1);
for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
var child = children_1[_i];
this.traverse(child, parent_1);
}
}
this._enter(node, parent);
};
return Traverse;
}());
var traverse = function (root, options) {
return new Traverse(options).traverse(root);
};
} else if (offset) {
jsxNodes.push(node);
} else {
acc.push(node);
}
if (index === length - 1 && jsxNodes.length > 0) {
acc.push(this.combineLeftJsxNodes(jsxNodes, parent));
}
return acc;
}, []);
}
traverse(node, parent) {
if (!node) {
return;
}
if ("children" in node) {
const parent2 = node;
parent2.children = this.combineJsxNodes(parent2.children, parent2);
for (const child of parent2.children) {
this.traverse(child, parent2);
}
}
this._enter(node, parent);
}
}
const traverse = (root, options) => new Traverse(options).traverse(root);
var mdProcessor = unified().use(remarkParse).freeze();
var mdxProcessor = mdProcessor().use(remarkMdx).freeze();
var AST_PROPS = ['body', 'comments', 'tokens'];
var ES_NODE_TYPES = ['export', 'import', 'jsx'];
var LOC_ERROR_PROPERTIES = ['column', 'lineNumber'];
var DEFAULT_EXTENSIONS = ['.mdx'];
var MARKDOWN_EXTENSIONS = ['.md'];
var DEFAULT_PARSER_OPTIONS = {
comment: true,
ecmaFeatures: {
jsx: true,
},
ecmaVersion: new Date().getUTCFullYear(),
sourceType: 'module',
tokens: true,
filePath: '__placeholder__.mdx',
// required for @typescript-eslint/parser
// reference: https://github.com/typescript-eslint/typescript-eslint/pull/2028
loc: true,
range: true,
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var JSX_WRAPPER_START = '<$>';
var JSX_WRAPPER_END = '</$>';
var OFFSET = JSX_WRAPPER_START.length;
var Parser = /** @class */ (function () {
function Parser() {
// @internal
this._options = DEFAULT_PARSER_OPTIONS;
this.parse = this.parse.bind(this);
this.parseForESLint = this.parseForESLint.bind(this);
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const mdProcessor = unified().use(remarkParse).freeze();
const mdxProcessor = mdProcessor().use(remarkMdx).freeze();
const AST_PROPS = ["body", "comments", "tokens"];
const ES_NODE_TYPES = ["export", "import", "jsx"];
const LOC_ERROR_PROPERTIES = ["column", "lineNumber"];
const DEFAULT_EXTENSIONS = [".mdx"];
const MARKDOWN_EXTENSIONS = [".md"];
const DEFAULT_PARSER_OPTIONS = {
comment: true,
ecmaFeatures: {
jsx: true
},
ecmaVersion: new Date().getUTCFullYear(),
sourceType: "module",
tokens: true,
filePath: "__placeholder__.mdx",
loc: true,
range: true
};
const JSX_WRAPPER_START = "<$>";
const JSX_WRAPPER_END = "</$>";
const OFFSET = JSX_WRAPPER_START.length;
class Parser {
constructor() {
this._options = DEFAULT_PARSER_OPTIONS;
this.parse = this.parse.bind(this);
this.parseForESLint = this.parseForESLint.bind(this);
}
normalizeJsxNode(node, parent, options = this._options) {
const value = node.value;
if (node.type !== "jsx" || isComment(value)) {
return node;
}
Parser.prototype.normalizeJsxNode = function (node, parent, options) {
if (options === void 0) { options = this._options; }
var value = node.value;
if (node.type !== 'jsx' || isComment(value)) {
return node;
}
var commentContent = COMMENT_CONTENT_REGEX.exec(value);
if (commentContent) {
var comments_1 = [];
var _a = node.position.start, line_1 = _a.line, column_1 = _a.column, startOffset_1 = _a.offset, data = node.data;
Object.assign(node, {
data: __assign(__assign({}, data), { jsxType: 'JSXElementWithHTMLComments', comments: comments_1,
// jsx in paragraph is considered as plain html in mdx, what means html style comments are valid
// TODO: in this case, jsx style comments could be a mistake
inline: !!parent && parent.type !== 'root' }),
value: value.replace(COMMENT_CONTENT_REGEX_GLOBAL, function (matched, $0, $1, $2, offset) {
var endOffset = offset + matched.length;
var startLines = value.slice(0, offset).split('\n');
var endLines = value.slice(0, endOffset).split('\n');
var fixed = "{/" + '*'.repeat($0.length - 2) + $1 + '*'.repeat($2.length - 2) + "/}";
var startLineOffset = startLines.length - 1;
var endLineOffset = endLines.length - 1;
comments_1.push({
fixed: fixed,
// ! eslint ast column is 0-indexed, but unified is 1-indexed
loc: {
start: {
line: line_1 + startLineOffset,
column: last(startLines).length +
(startLineOffset ? 0 : column_1 - 1),
offset: startOffset_1 + offset,
},
end: {
line: line_1 + endLineOffset,
column: last(endLines).length + (endLineOffset ? 0 : column_1 - 1),
offset: startOffset_1 + endOffset,
},
},
origin: matched,
});
return fixed;
}),
});
}
return this._normalizeJsxNodes(node, options);
const commentContent = COMMENT_CONTENT_REGEX.exec(value);
if (commentContent) {
const comments = [];
const {
position: {
start: { line, column, offset: startOffset }
},
data
} = node;
Object.assign(node, {
data: __spreadProps(__spreadValues({}, data), {
jsxType: "JSXElementWithHTMLComments",
comments,
inline: !!parent && parent.type !== "root"
}),
value: value.replace(COMMENT_CONTENT_REGEX_GLOBAL, (matched, $0, $1, $2, offset) => {
const endOffset = offset + matched.length;
const startLines = value.slice(0, offset).split("\n");
const endLines = value.slice(0, endOffset).split("\n");
const fixed = `{/${"*".repeat($0.length - 2)}${$1}${"*".repeat($2.length - 2)}/}`;
const startLineOffset = startLines.length - 1;
const endLineOffset = endLines.length - 1;
comments.push({
fixed,
loc: {
start: {
line: line + startLineOffset,
column: last(startLines).length + (startLineOffset ? 0 : column - 1),
offset: startOffset + offset
},
end: {
line: line + endLineOffset,
column: last(endLines).length + (endLineOffset ? 0 : column - 1),
offset: startOffset + endOffset
}
},
origin: matched
});
return fixed;
})
});
}
return this._normalizeJsxNodes(node, options);
}
parse(code, options) {
return this.parseForESLint(code, options).ast;
}
parseForESLint(code, options) {
const extname = path.extname(options.filePath);
const isMdx = DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(extname);
const isMarkdown = MARKDOWN_EXTENSIONS.concat(options.markdownExtensions || []).includes(extname);
if (!isMdx && !isMarkdown) {
return this._eslintParse(code, options);
}
const root = (isMdx ? mdxProcessor : mdProcessor).parse(code);
this._ast = __spreadProps(__spreadValues({}, normalizePosition(root.position)), {
type: "Program",
sourceType: options.sourceType || "module",
body: [],
comments: [],
tokens: []
});
this._services = {
JSXElementsWithHTMLComments: []
};
Parser.prototype.parse = function (code, options) {
return this.parseForESLint(code, options).ast;
};
Parser.prototype.parseForESLint = function (code, options) {
var _this = this;
var extname = path.extname(options.filePath);
var isMdx = DEFAULT_EXTENSIONS.concat(options.extensions || []).includes(extname);
var isMarkdown = MARKDOWN_EXTENSIONS.concat(options.markdownExtensions || []).includes(extname);
if (!isMdx && !isMarkdown) {
return this._eslintParse(code, options);
if (isMdx) {
traverse(root, {
code,
enter: (node, parent) => {
if (!ES_NODE_TYPES.includes(node.type)) {
return;
}
for (const normalizedNode of arrayify(this.normalizeJsxNode(node, parent, options))) {
this._nodeToAst(code, normalizedNode, options);
}
}
var root = (isMdx ? mdxProcessor : mdProcessor).parse(code);
this._ast = __assign(__assign({}, normalizePosition(root.position)), { type: 'Program', sourceType: options.sourceType || 'module', body: [], comments: [], tokens: [] });
this._services = {
JSXElementsWithHTMLComments: [],
};
if (isMdx) {
traverse(root, {
code: code,
enter: function (node, parent) {
if (!ES_NODE_TYPES.includes(node.type)) {
return;
}
for (var _i = 0, _a = arrayify(_this.normalizeJsxNode(node, parent, options)); _i < _a.length; _i++) {
var normalizedNode = _a[_i];
_this._nodeToAst(code, normalizedNode, options);
}
},
});
}
return {
ast: this._ast,
services: this._services,
};
});
}
return {
ast: this._ast,
services: this._services
};
// @internal
Parser.prototype._eslintParse = function (code, options) {
if (!this._parsers || options.parser !== this._options.parser) {
this._parsers = normalizeParser(options.parser);
}
_eslintParse(code, options) {
if (!this._parsers || options.parser !== this._options.parser) {
this._parsers = normalizeParser(options.parser);
}
if (options.filePath && this._options !== options) {
Object.assign(this._options, options);
}
let program;
let parseError;
for (const parser2 of this._parsers) {
try {
program = parser2(code, this._options);
break;
} catch (err) {
if (!parseError) {
parseError = err;
}
/* istanbul ignore else */
if (options.filePath && this._options !== options) {
Object.assign(this._options, options);
}
}
if (!program && parseError) {
throw parseError;
}
return "ast" in program && program.ast ? program : { ast: program };
}
_normalizeJsxNodes(node, options) {
const value = node.value;
let program;
try {
program = this._eslintParse(`${JSX_WRAPPER_START}${value}${JSX_WRAPPER_END}`, options).ast;
} catch (err) {
if (hasProperties(err, LOC_ERROR_PROPERTIES)) {
const {
position: { start }
} = node;
if ("index" in err) {
err.index += start.offset - OFFSET;
} else if ("pos" in err) {
err.pos += start.offset - OFFSET;
}
var program;
var parseError;
for (var _i = 0, _a = this._parsers; _i < _a.length; _i++) {
var parser_1 = _a[_i];
try {
program = parser_1(code, this._options);
break;
}
catch (err) {
if (!parseError) {
parseError = err;
}
}
}
if (!program && parseError) {
throw parseError;
}
/* istanbul ignore next */
return ('ast' in program && program.ast
? program
: { ast: program });
};
// fix adjacent JSX nodes
// @internal
// eslint-disable-next-line sonarjs/cognitive-complexity
Parser.prototype._normalizeJsxNodes = function (node, options) {
var value = node.value;
var program;
try {
// wrap into single element which is valid jsx but not valid jsx in mdx, so that it won't break on adjacent JSX nodes
program = this._eslintParse("" + JSX_WRAPPER_START + value + JSX_WRAPPER_END, options).ast;
}
catch (err) {
if (hasProperties(err, LOC_ERROR_PROPERTIES)) {
var start = node.position.start;
/* istanbul ignore else */
if ('index' in err) {
err.index += start.offset - OFFSET;
}
else if ('pos' in err) {
err.pos += start.offset - OFFSET;
}
err.column =
/* istanbul ignore next */
err.lineNumber > 1 ? err.column : err.column + start.column - OFFSET;
err.lineNumber += start.line - 1;
throw err;
}
return node;
}
var expression = program.body[0].expression;
if (!isJsxNode(expression) || expression.children.length <= 1) {
return node;
}
var _a = node.position.start, line = _a.line, offset = _a.offset, data = node.data;
return expression.children.reduce(function (nodes, jsNode) {
if (!isJsxNode(jsNode)) {
return nodes;
}
/* istanbul ignore next */
var nodeStart = jsNode.start, nodeEnd = jsNode.end, _a = jsNode.loc, _b = _a === void 0 ? {
start: { column: nodeStart, line: 1 },
end: { column: nodeEnd, line: 1 },
} : _a, start = _b.start, end = _b.end, _c = jsNode.range, range = _c === void 0 ? [nodeStart, nodeEnd] : _c;
var startLine = line + start.line - 1;
var endLine = line + end.line - 1;
var startOffset = range[0] - OFFSET;
var endOffset = range[1] - OFFSET;
nodes.push({
type: 'jsx',
data: nodes.length > 0 ? null : data,
value: value.slice(startOffset, endOffset),
position: {
start: {
line: startLine,
column: line === startLine ? start.column - OFFSET : start.column,
offset: offset + startOffset,
},
end: {
line: endLine,
column: line === startLine ? end.column - OFFSET : end.column,
offset: offset + endOffset,
},
},
});
return nodes;
}, []);
};
// @internal
Parser.prototype._nodeToAst = function (code, node, options) {
var _a;
if (node.data && node.data.jsxType === 'JSXElementWithHTMLComments') {
this._services.JSXElementsWithHTMLComments.push(node);
}
var value = node.value;
var _b = normalizePosition(node.position), loc = _b.loc, start = _b.start, end = _b.end;
// fix #4
if (isComment(value)) {
var comment = COMMENT_CONTENT_REGEX.exec(value)[2];
this._ast.comments.push({
type: 'Block',
value: comment,
loc: loc,
range: [start, end],
});
return;
}
var startLine = loc.start.line - 1; // ! line is 1-indexed, change to 0-indexed to simplify usage
var program;
try {
program = this._eslintParse(value, options).ast;
}
catch (e) {
/* istanbul ignore if */
if (hasProperties(e, LOC_ERROR_PROPERTIES)) {
// should be handled by `_normalizeJsxNodes`, just for robustness
e.index += start;
e.column = e.lineNumber > 1 ? e.column : e.column + loc.start.column;
e.lineNumber += startLine;
}
throw e;
}
var startPoint = {
err.column = err.lineNumber > 1 ? err.column : err.column + start.column - OFFSET;
err.lineNumber += start.line - 1;
throw err;
}
return node;
}
const { expression } = program.body[0];
if (!isJsxNode(expression) || expression.children.length <= 1) {
return node;
}
const {
position: {
start: { line, offset }
},
data
} = node;
return expression.children.reduce((nodes, jsNode) => {
if (!isJsxNode(jsNode)) {
return nodes;
}
const {
start: nodeStart,
end: nodeEnd,
loc: { start, end } = {
start: { column: nodeStart, line: 1 },
end: { column: nodeEnd, line: 1 }
},
range = [nodeStart, nodeEnd]
} = jsNode;
const startLine = line + start.line - 1;
const endLine = line + end.line - 1;
const startOffset = range[0] - OFFSET;
const endOffset = range[1] - OFFSET;
nodes.push({
type: "jsx",
data: nodes.length > 0 ? null : data,
value: value.slice(startOffset, endOffset),
position: {
start: {
line: startLine,
// #279 related
column: getPositionAt(code, start).column,
offset: start,
};
for (var _i = 0, AST_PROPS_1 = AST_PROPS; _i < AST_PROPS_1.length; _i++) {
var prop = AST_PROPS_1[_i];
(_a = this._ast[prop]).push.apply(_a, program[prop].map(function (item) {
return restoreNodeLocation(item, startPoint);
}));
column: line === startLine ? start.column - OFFSET : start.column,
offset: offset + startOffset
},
end: {
line: endLine,
column: line === startLine ? end.column - OFFSET : end.column,
offset: offset + endOffset
}
}
});
return nodes;
}, []);
}
_nodeToAst(code, node, options) {
if (node.data && node.data.jsxType === "JSXElementWithHTMLComments") {
this._services.JSXElementsWithHTMLComments.push(node);
}
const value = node.value;
const { loc, start, end } = normalizePosition(node.position);
if (isComment(value)) {
const comment = COMMENT_CONTENT_REGEX.exec(value)[2];
this._ast.comments.push({
type: "Block",
value: comment,
loc,
range: [start, end]
});
return;
}
const startLine = loc.start.line - 1;
let program;
try {
program = this._eslintParse(value, options).ast;
} catch (e) {
if (hasProperties(e, LOC_ERROR_PROPERTIES)) {
e.index += start;
e.column = e.lineNumber > 1 ? e.column : e.column + loc.start.column;
e.lineNumber += startLine;
}
throw e;
}
const startPoint = {
line: startLine,
column: getPositionAt(code, start).column,
offset: start
};
return Parser;
}());
var parser = new Parser();
// eslint-disable-next-line @typescript-eslint/unbound-method
var parse = parser.parse, parseForESLint = parser.parseForESLint;
for (const prop of AST_PROPS)
this._ast[prop].push(...program[prop].map((item) => restoreNodeLocation(item, startPoint)));
}
}
const parser = new Parser();
const { parse, parseForESLint } = parser;
export { AST_PROPS, CLOSE_TAG_REGEX, COMMENT_CONTENT_REGEX, COMMENT_CONTENT_REGEX_GLOBAL, COMMENT_REGEX, DEFAULT_EXTENSIONS, DEFAULT_PARSER_OPTIONS, ES_NODE_TYPES, FALLBACK_PARSERS, JSX_TYPES, LOC_ERROR_PROPERTIES, MARKDOWN_EXTENSIONS, OPEN_CLOSE_TAG_REGEX, OPEN_TAG_REGEX, Parser, SELF_CLOSING_TAG_REGEX, Traverse, arrayify, closeTag, comment, commentClose, commentContent, commentOpen, first, getPositionAt, hasProperties, isCloseTag, isComment, isJsxNode, isOpenCloseTag, isOpenTag, isSelfClosingTag, last, mdProcessor, mdxProcessor, normalizeParser, normalizePosition, openTag, parse, parseForESLint, parser, restoreNodeLocation, selfClosingTag, traverse };

@@ -119,2 +119,3 @@ "use strict";

exports.arrayify = arrayify;
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- test coverage
const first = (items) => items && items[0];

@@ -121,0 +122,0 @@ exports.first = first;

import type { AST, Linter } from 'eslint';
import unified from 'unified';
import type { Node, Parent } from 'unist';
import type { ParserOptions } from './types';
import type { Node, Parent, ParserOptions } from './types';
export declare const mdProcessor: unified.FrozenProcessor<unified.Settings>;

@@ -15,3 +14,3 @@ export declare const mdxProcessor: unified.FrozenProcessor<unified.Settings>;

constructor();
normalizeJsxNode(node: Node, parent?: Parent, options?: ParserOptions): Node | Node[];
normalizeJsxNode(node: Node, parent?: Parent, options?: ParserOptions): Node<string> | Node<string>[];
parse(code: string, options: ParserOptions): AST.Program;

@@ -18,0 +17,0 @@ parseForESLint(code: string, options: ParserOptions): Linter.ESLintParseResult;

@@ -147,5 +147,3 @@ "use strict";

/* istanbul ignore next */
return ('ast' in program && program.ast
? program
: { ast: program });
return ('ast' in program && program.ast ? program : { ast: program });
}

@@ -152,0 +150,0 @@ // fix adjacent JSX nodes

@@ -1,3 +0,2 @@

import type { Node, Parent } from 'unist';
import type { TraverseOptions } from './types';
import type { Node, Parent, TraverseOptions } from './types';
export declare class Traverse {

@@ -7,5 +6,5 @@ code: string;

combineLeftJsxNodes(jsxNodes: Node[], parent?: Parent): Node;
combineJsxNodes(nodes: Node[], parent?: Parent): Node[];
combineJsxNodes(nodes: Node[], parent?: Parent): Node<string>[];
traverse(node: Node, parent?: Parent): void;
}
export declare const traverse: (root: Parent, options: TraverseOptions) => void;

@@ -118,7 +118,6 @@ "use strict";

}
let children = node.children;
if (children) {
if ('children' in node) {
const parent = node;
children = node.children = this.combineJsxNodes(children, parent);
for (const child of children) {
parent.children = this.combineJsxNodes(parent.children, parent);
for (const child of parent.children) {
this.traverse(child, parent);

@@ -125,0 +124,0 @@ }

import type { JSXElement, JSXFragment } from '@babel/types';
import type { AST, Linter } from 'eslint';
import type { Node, Parent, Point } from 'unist';
import type { Node as _Node, Parent as _Parent, Point } from 'unist';
export interface Node<T = string> extends _Node {
value?: T;
}
export interface Parent<T = string> extends _Parent {
children: Array<Node<T>>;
}
export declare type Arrayable<T> = T[] | readonly T[];

@@ -10,10 +16,10 @@ export declare type ValueOf<T> = T extends {

} ? N : never;
export declare type JsxNode = (JSXElement | JSXFragment) & {
export declare type JsxNode = {
range: [number, number];
};
} & (JSXElement | JSXFragment);
export declare type ParserFn = (code: string, options: Linter.ParserOptions) => AST.Program | Linter.ESLintParseResult;
export declare type ParserConfig = {
parse: ParserFn;
} | {
parseForESLint: ParserFn;
} | {
parse: ParserFn;
};

@@ -27,6 +33,6 @@ export interface LocationError {

export interface ParserOptions extends Linter.ParserOptions {
extensions?: string | string[];
markdownExtensions?: string | string[];
extensions?: string[] | string;
markdownExtensions?: string[] | string;
filePath?: string;
parser?: string | ParserConfig | ParserFn;
parser?: ParserConfig | ParserFn | string;
}

@@ -33,0 +39,0 @@ export declare type Traverser = (node: Node, parent?: Parent) => void;

{
"name": "eslint-mdx",
"version": "1.13.0",
"version": "1.14.0",
"description": "ESLint Parser for MDX",

@@ -38,6 +38,6 @@ "repository": "git+https://github.com/mdx-js/eslint-mdx.git",

"remark-parse": "^8.0.3",
"tslib": "^2.2.0",
"tslib": "^2.3.0",
"unified": "^9.2.1"
},
"gitHead": "ebf3923730d1079b553991883c016e0c2f384bf7"
"gitHead": "18283932bc37541dd6cbde2d678816a4ac94209c"
}

@@ -13,4 +13,3 @@ <p align="center">

[![Travis](https://img.shields.io/travis/com/mdx-js/eslint-mdx.svg)](https://travis-ci.com/mdx-js/eslint-mdx)
[![Codacy Grade](https://img.shields.io/codacy/grade/4ea8225261c04837995a858676caae4b)](https://www.codacy.com/app/JounQin/eslint-mdx)
[![GitHub Actions](https://github.com/mdx-js/eslint-mdx/workflows/CI/badge.svg)](https://github.com/mdx-js/eslint-mdx/actions/workflows/ci.yml)
[![Codecov](https://img.shields.io/codecov/c/gh/mdx-js/eslint-mdx)](https://codecov.io/gh/mdx-js/eslint-mdx)

@@ -24,3 +23,2 @@ [![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fmdx-js%2Feslint-mdx%2Fmaster%2Fpackage.json)](https://github.com/plantain-00/type-coverage)

[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org)
[![codechecks.io](https://raw.githubusercontent.com/codechecks/docs/master/images/badges/badge-default.svg?sanitize=true)](https://codechecks.io)

@@ -27,0 +25,0 @@ > [ESLint][] Parser/Plugin for [MDX][], helps you lint all ES syntaxes.

declare module 'remark-mdx' {
import type * as unified from 'unified'
const mdx: unified.Attacher
export = mdx
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc