Skip to content

Commit

Permalink
feat!: experimentally support react-mdx@next
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed Mar 15, 2021
1 parent abe30cb commit 774d940
Show file tree
Hide file tree
Showing 28 changed files with 592 additions and 1,077 deletions.
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ This project is a [lerna][] monorepo, so packages releasing is controlled by [le
2. You need a GitHub token with a `public_repo` scope as `GH_TOKEN` in the environment to publish
3. Run `yarn release` simply, or `GH_TOKEN=xxx yarn release` to export `GH_TOKEN` at one time.

### Release a bete next version

Run `yarn release-next`

[contributing]: https://mdxjs.com/contributing
[lerna]: https://github.com/lerna/lerna
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
- [Usage](#usage)
- [Parser Options](#parser-options)
- [Rules](#rules)
- [mdx/no-jsx-html-comments](#mdxno-jsx-html-comments)
- [mdx/no-unescaped-entities](#mdxno-unescaped-entities)
- [mdx/no-unused-expressions](#mdxno-unused-expressions)
- [mdx/remark](#mdxremark)
Expand Down Expand Up @@ -179,10 +178,6 @@ npm i -D eslint-plugin-mdx

## Rules

### mdx/no-jsx-html-comments

_Fixable_: HTML style comments in jsx block is invalid, this rule will help you to fix it by transforming it to JSX style comments.

### mdx/no-unescaped-entities

Inline JSX like `Inline <Component />` is supported by [MDX][], but rule `react/no-unescaped-entities` from [eslint-plugin-react][] is incompatible with it, `mdx/no-unescaped-entities` is the replacement, so make sure that you've turned off the original `no-unescaped-entities` rule.
Expand Down
4 changes: 2 additions & 2 deletions lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"command": {
"version": {
"allowBranch": [
"develop",
"master"
"master",
"next"
]
},
"publish": {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"postinstall": "yarn-deduplicate --strategy fewer || exit 0",
"prerelease": "yarn build",
"release": "lerna publish --conventional-commits --create-release github --yes",
"release-next": "lerna publish --conventional-prerelease --preid next --pre-dist-tag next --yes",
"test": "jest",
"typecov": "type-coverage"
},
Expand All @@ -40,7 +41,7 @@
"ts-jest": "^26.5.3",
"ts-node": "^9.1.1",
"tslint": "^6.1.3",
"type-coverage": "^2.16.3",
"type-coverage": "^2.17.0",
"typescript": "^4.2.3",
"yarn-deduplicate": "^3.1.0"
},
Expand Down
5 changes: 0 additions & 5 deletions packages/eslint-mdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
- [Usage](#usage)
- [Parser Options](#parser-options)
- [Rules](#rules)
- [mdx/no-jsx-html-comments](#mdxno-jsx-html-comments)
- [mdx/no-unescaped-entities](#mdxno-unescaped-entities)
- [mdx/no-unused-expressions](#mdxno-unused-expressions)
- [mdx/remark](#mdxremark)
Expand Down Expand Up @@ -179,10 +178,6 @@ npm i -D eslint-plugin-mdx

## Rules

### mdx/no-jsx-html-comments

_Fixable_: HTML style comments in jsx block is invalid, this rule will help you to fix it by transforming it to JSX style comments.

### mdx/no-unescaped-entities

Inline JSX like `Inline <Component />` is supported by [MDX][], but rule `react/no-unescaped-entities` from [eslint-plugin-react][] is incompatible with it, `mdx/no-unescaped-entities` is the replacement, so make sure that you've turned off the original `no-unescaped-entities` rule.
Expand Down
7 changes: 3 additions & 4 deletions packages/eslint-mdx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"fesm5": "lib/esm",
"types": "lib",
"files": [
"lib",
"typings.d.ts"
"lib"
],
"keywords": [
"eslint",
Expand All @@ -33,8 +32,8 @@
"eslint": ">=5.0.0"
},
"dependencies": {
"remark-mdx": "^1.6.22",
"remark-parse": "^8.0.3",
"remark-mdx": "https://gitpkg.now.sh/mdx-js/mdx/packages/remark-mdx?main",
"remark-parse": "^9.0.0",
"tslib": "^2.1.0",
"unified": "^9.2.1"
}
Expand Down
101 changes: 47 additions & 54 deletions packages/eslint-mdx/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/// <reference path="../typings.d.ts" />

import type { Linter } from 'eslint'
import type { SourceLocation } from 'estree'
import type { Position } from 'unist'
import type { Node, Position } from 'unist'

import type { Arrayable, JsxNode, ParserFn, ParserOptions } from './types'
import type {
JsxNode,
MdxNode,
ParserFn,
ParserOptions,
ValueOf,
} from './types'

export const FALLBACK_PARSERS = [
'@typescript-eslint/parser',
Expand All @@ -18,9 +22,43 @@ export const JSX_TYPES = ['JSXElement', 'JSXFragment']
export const isJsxNode = (node: { type: string }): node is JsxNode =>
JSX_TYPES.includes(node.type)

export const MdxNodeType = {
FLOW_EXPRESSION: 'mdxFlowExpression',
JSX_FLOW_ELEMENT: 'mdxJsxFlowElement',
JSX_TEXT_ELEMENT: 'mdxJsxTextElement',
TEXT_EXPRESSION: 'mdxTextExpression',
JS_ESM: 'mdxjsEsm',
} as const

// eslint-disable-next-line @typescript-eslint/no-type-alias
export type MdxNodeType = ValueOf<typeof MdxNodeType>

export const MDX_NODE_TYPES = [
MdxNodeType.FLOW_EXPRESSION,
MdxNodeType.JSX_FLOW_ELEMENT,
MdxNodeType.JSX_TEXT_ELEMENT,
MdxNodeType.TEXT_EXPRESSION,
MdxNodeType.JS_ESM,
] as const

export const isMdxNode = (node: Node): node is MdxNode =>
MDX_NODE_TYPES.includes(node.type as MdxNodeType)

/**
* @internal
* only for testing
*/
export const parsersCache = new Map<ParserOptions['parser'], ParserFn[]>()

// eslint-disable-next-line sonarjs/cognitive-complexity
export const normalizeParser = (parser?: ParserOptions['parser']) => {
if (parsersCache.has(parser)) {
return parsersCache.get(parser)
}

if (parser) {
const originalParser = parser

if (typeof parser === 'string') {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
parser = require(parser) as ParserOptions['parser']
Expand All @@ -36,7 +74,9 @@ export const normalizeParser = (parser?: ParserOptions['parser']) => {
throw new TypeError(`Invalid custom parser for \`eslint-mdx\`: ${parser}`)
}

return [parser]
const parsers = [parser]
parsersCache.set(originalParser, parsers)
return parsers
}

const parsers: ParserFn[] = []
Expand All @@ -60,6 +100,8 @@ export const normalizeParser = (parser?: ParserOptions['parser']) => {
} catch {}
}

parsersCache.set(parser, parsers)

return parsers
}

Expand All @@ -82,54 +124,5 @@ export const normalizePosition = (loc: Position): Omit<BaseNode, 'type'> => {
}
}

export const hasProperties = <T, P extends keyof T = keyof T>(
obj: unknown,
properties: Arrayable<P>,
): obj is T =>
typeof obj === 'object' &&
obj &&
properties.every(property => property in obj)

export const restoreNodeLocation = <T>(
node: T,
startLine: number,
offset: number,
): T => {
if (node && typeof node === 'object') {
for (const value of Object.values(node)) {
restoreNodeLocation(value, startLine, offset)
}
}

if (!hasProperties<BaseNode>(node, ['loc', 'range'])) {
return node
}

const {
loc: { start: startLoc, end: endLoc },
range,
} = node
const start = range[0] + offset
const end = range[1] + offset

return Object.assign(node, {
start,
end,
range: [start, end],
loc: {
start: {
line: startLine + startLoc.line,
column: startLoc.column,
},
end: {
line: startLine + endLoc.line,
column: endLoc.column,
},
},
})
}

export const first = <T>(items: T[] | readonly T[]) => items && items[0]

export const last = <T>(items: T[] | readonly T[]) =>
items && items[items.length - 1]
Loading

0 comments on commit 774d940

Please sign in to comment.