From 919b08e3a868f12487d684e89683348c75c9a258 Mon Sep 17 00:00:00 2001 From: JounQin Date: Sun, 10 Dec 2023 21:15:51 +0800 Subject: [PATCH] fix: support heading in jsx as MDXJSXHeading estree node --- .eslintrc.js | 6 +++ README.md | 24 +++++++++++ packages/eslint-mdx/README.md | 24 +++++++++++ packages/eslint-mdx/src/types.ts | 9 +++++ packages/eslint-mdx/src/worker.ts | 19 +++++++-- packages/eslint-plugin-mdx/README.md | 24 +++++++++++ test/__snapshots__/fixtures.test.ts.snap | 18 --------- test/__snapshots__/parser.test.ts.snap | 51 +++++++++++++++++++++++- 8 files changed, 153 insertions(+), 22 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 16cfbb4..92013a5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,5 +29,11 @@ module.exports = { 'mdx/code-blocks': true, }, }, + { + files: '**/*.{md,mdx}/**/*.ts', + rules: { + 'no-magic-numbers': 'off', + }, + }, ], } diff --git a/README.md b/README.md index 84804ef..e6cbe71 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ - [Parser Options](#parser-options) - [Parser API](#parser-api) - [`MDXJSXCode`](#mdxjsxcode) + - [`MDXJSXHeading`](#mdxjsxheading) - [Typings](#typings) - [Rules](#rules) - [mdx/remark](#mdxremark) @@ -160,10 +161,25 @@ export function foo() { See also +### `MDXJSXHeading` + +A new `MDXJSXHeading` estree node type is exported from `eslint-mdx` which represents code blocks in `mdx` like the following: + +```mdx +
+ +# Here's a text gradient short code! + +
+``` + +See also + ### Typings ```ts import type { BaseNode } from 'estree' +import type { JSXElement } from 'estree-jsx' export interface MDXJSXCode extends BaseNode { type: 'MDXJSXCode' @@ -171,6 +187,14 @@ export interface MDXJSXCode extends BaseNode { lang?: string | null meta?: string | null } + +export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6 + +export interface MDXJSXHeading extends BaseNode { + type: 'MDXJSXHeading' + depth: HeadingDepth + children: JSXElement['children'] +} ``` ## Rules diff --git a/packages/eslint-mdx/README.md b/packages/eslint-mdx/README.md index 84804ef..e6cbe71 100644 --- a/packages/eslint-mdx/README.md +++ b/packages/eslint-mdx/README.md @@ -37,6 +37,7 @@ - [Parser Options](#parser-options) - [Parser API](#parser-api) - [`MDXJSXCode`](#mdxjsxcode) + - [`MDXJSXHeading`](#mdxjsxheading) - [Typings](#typings) - [Rules](#rules) - [mdx/remark](#mdxremark) @@ -160,10 +161,25 @@ export function foo() { See also +### `MDXJSXHeading` + +A new `MDXJSXHeading` estree node type is exported from `eslint-mdx` which represents code blocks in `mdx` like the following: + +```mdx +
+ +# Here's a text gradient short code! + +
+``` + +See also + ### Typings ```ts import type { BaseNode } from 'estree' +import type { JSXElement } from 'estree-jsx' export interface MDXJSXCode extends BaseNode { type: 'MDXJSXCode' @@ -171,6 +187,14 @@ export interface MDXJSXCode extends BaseNode { lang?: string | null meta?: string | null } + +export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6 + +export interface MDXJSXHeading extends BaseNode { + type: 'MDXJSXHeading' + depth: HeadingDepth + children: JSXElement['children'] +} ``` ## Rules diff --git a/packages/eslint-mdx/src/types.ts b/packages/eslint-mdx/src/types.ts index 65cdce9..ac1bcc2 100644 --- a/packages/eslint-mdx/src/types.ts +++ b/packages/eslint-mdx/src/types.ts @@ -1,6 +1,7 @@ import type { Position } from 'acorn' import type { AST, Linter } from 'eslint' import type { BaseNode, Program } from 'estree' +import type { JSXElement } from 'estree-jsx' import type { Root } from 'mdast' import type { VFileOptions } from 'vfile' import type { VFileMessage } from 'vfile-message' @@ -54,3 +55,11 @@ export interface MDXJSXCode extends BaseNode { lang?: string | null meta?: string | null } + +export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6 + +export interface MDXJSXHeading extends BaseNode { + type: 'MDXJSXHeading' + depth: HeadingDepth + children: JSXElement['children'] +} diff --git a/packages/eslint-mdx/src/worker.ts b/packages/eslint-mdx/src/worker.ts index d274353..ae24c07 100644 --- a/packages/eslint-mdx/src/worker.ts +++ b/packages/eslint-mdx/src/worker.ts @@ -28,6 +28,7 @@ import type { import type { BlockContent, Code, + Heading, Paragraph, PhrasingContent, Literal, @@ -51,6 +52,7 @@ import { restoreTokens } from './tokens' import type { Arrayable, MDXJSXCode, + MDXJSXHeading, NormalPosition, WorkerOptions, WorkerResult, @@ -442,14 +444,25 @@ runAsWorker( if (node.type === 'code') { const { lang, meta, value } = node as Code - const jsxCode: MDXJSXCode = { + const mdxJsxCode: MDXJSXCode = { ...normalizeNode(start, end), - type: 'MDXJSXCode' as const, + type: 'MDXJSXCode', lang, meta, value, } - return jsxCode + return mdxJsxCode + } + + if (node.type === 'heading') { + const { depth } = node as Heading + const mdxJsxHeading: MDXJSXHeading = { + ...normalizeNode(start, end), + type: 'MDXJSXHeading', + depth, + children: handleChildren(node), + } + return mdxJsxHeading } if (node.type === 'text') { diff --git a/packages/eslint-plugin-mdx/README.md b/packages/eslint-plugin-mdx/README.md index 84804ef..e6cbe71 100644 --- a/packages/eslint-plugin-mdx/README.md +++ b/packages/eslint-plugin-mdx/README.md @@ -37,6 +37,7 @@ - [Parser Options](#parser-options) - [Parser API](#parser-api) - [`MDXJSXCode`](#mdxjsxcode) + - [`MDXJSXHeading`](#mdxjsxheading) - [Typings](#typings) - [Rules](#rules) - [mdx/remark](#mdxremark) @@ -160,10 +161,25 @@ export function foo() { See also +### `MDXJSXHeading` + +A new `MDXJSXHeading` estree node type is exported from `eslint-mdx` which represents code blocks in `mdx` like the following: + +```mdx +
+ +# Here's a text gradient short code! + +
+``` + +See also + ### Typings ```ts import type { BaseNode } from 'estree' +import type { JSXElement } from 'estree-jsx' export interface MDXJSXCode extends BaseNode { type: 'MDXJSXCode' @@ -171,6 +187,14 @@ export interface MDXJSXCode extends BaseNode { lang?: string | null meta?: string | null } + +export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6 + +export interface MDXJSXHeading extends BaseNode { + type: 'MDXJSXHeading' + depth: HeadingDepth + children: JSXElement['children'] +} ``` ## Rules diff --git a/test/__snapshots__/fixtures.test.ts.snap b/test/__snapshots__/fixtures.test.ts.snap index 9796a1a..0f29a50 100644 --- a/test/__snapshots__/fixtures.test.ts.snap +++ b/test/__snapshots__/fixtures.test.ts.snap @@ -1062,24 +1062,6 @@ Here's a YouTube shortcode: "ruleId": "react/jsx-no-undef", "severity": 2, }, - { - "column": 1, - "endColumn": 15, - "endLine": 33, - "fix": { - "range": [ - 648, - 703, - ], - "text": " />", - }, - "line": 33, - "message": "Empty components are self-closing", - "messageId": "notSelfClosing", - "nodeType": "JSXOpeningElement", - "ruleId": "react/self-closing-comp", - "severity": 2, - }, { "column": 2, "endColumn": 14, diff --git a/test/__snapshots__/parser.test.ts.snap b/test/__snapshots__/parser.test.ts.snap index b8aac28..0b94dcc 100644 --- a/test/__snapshots__/parser.test.ts.snap +++ b/test/__snapshots__/parser.test.ts.snap @@ -40897,7 +40897,56 @@ exports[`parser should match all AST snapshots: blank-lines.mdx 1`] = ` { "end": 703, "expression": { - "children": [], + "children": [ + { + "children": [ + { + "end": 686, + "loc": { + "end": { + "column": 35, + "line": 35, + "offset": 686, + }, + "start": { + "column": 2, + "line": 35, + "offset": 653, + }, + }, + "range": [ + 653, + 686, + ], + "raw": "Here's a text gradient shortcode!", + "start": 653, + "type": "JSXText", + "value": "Here's a text gradient shortcode!", + }, + ], + "depth": 1, + "end": 686, + "loc": { + "end": { + "column": 35, + "line": 35, + "offset": 686, + }, + "start": { + "column": 0, + "line": 35, + "offset": 651, + }, + }, + "range": [ + 651, + 686, + ], + "raw": "# Here's a text gradient shortcode!", + "start": 651, + "type": "MDXJSXHeading", + }, + ], "closingElement": { "end": 703, "loc": {