Skip to content

Commit a46609e

Browse files
authored
feat(richtext-lexical): more lenient MDX JSON object parser that allows unquoted property keys (#10205)
Previously, the following MDX could not be parsed by lexical: ```tsx <RestExamples data={[ { operation: "Find" } ]} ``` Instead, it had to be converted into valid JSON: ```tsx <RestExamples data={[ { "operation": "Find" } ]} ``` This PR permits using the first example, as it swaps out JSON.parse with them ore lenient [json5](https://www.npmjs.com/package/json5) package parser
1 parent cf8c0ae commit a46609e

File tree

5 files changed

+52
-56
lines changed

5 files changed

+52
-56
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const defaultESLintIgnores = [
1919
'**/build/',
2020
'**/node_modules/',
2121
'**/temp/',
22+
'**/*.spec.ts',
2223
]
2324

2425
/** @typedef {import('eslint').Linter.Config} Config */

packages/richtext-lexical/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@
362362
"bson-objectid": "2.0.4",
363363
"dequal": "2.0.3",
364364
"escape-html": "1.0.3",
365+
"json5": "^2.2.3",
365366
"lexical": "0.20.0",
366367
"mdast-util-from-markdown": "2.0.2",
367368
"mdast-util-mdx-jsx": "3.1.3",

packages/richtext-lexical/src/utilities/jsx/extractPropsFromJSXPropsString.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import JSON5Import from 'json5'
2+
3+
const JSON5 = ('default' in JSON5Import ? JSON5Import.default : JSON5Import) as typeof JSON5Import
4+
15
/**
26
* Turns a JSX props string into an object.
37
*
@@ -78,7 +82,7 @@ function handleArray(propsString: string, startIndex: number): { newIndex: numbe
7882
i++
7983
}
8084

81-
return { newIndex: i, value: JSON.parse(`[${value}]`) }
85+
return { newIndex: i, value: JSON5.parse(`[${value}]`) }
8286
}
8387

8488
function handleQuotedString(
@@ -116,10 +120,10 @@ function handleObject(propsString: string, startIndex: number): { newIndex: numb
116120

117121
function parseObject(objString: string): Record<string, any> {
118122
if (objString[0] !== '{') {
119-
return JSON.parse(objString)
123+
return JSON5.parse(objString)
120124
}
121125

122-
const result = JSON.parse(objString.replace(/(\w+):/g, '"$1":'))
126+
const result = JSON5.parse(objString.replace(/(\w+):/g, '"$1":'))
123127

124128
return result
125129
}

packages/richtext-lexical/src/utilities/jsx/jsx.spec.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { propsToJSXString } from './jsx.js'
33

44
describe('jsx', () => {
55
describe('prop string to object', () => {
6-
const INPUT_AND_OUTPUT = [
6+
const INPUT_AND_OUTPUT: {
7+
input: string
8+
inputFromOutput?: string
9+
output: Record<string, any>
10+
}[] = [
711
{
812
input: 'key="value"',
913
output: {
@@ -112,6 +116,15 @@ describe('jsx', () => {
112116
update: true,
113117
},
114118
},
119+
{
120+
// Test if unquoted property keys in objects within arrays are supprted. This is
121+
// supported through the more lenient json5 parser, instead of using JSON.parse()
122+
input: 'key={[1, 2, { hello: "there" }]}',
123+
inputFromOutput: 'key={[1, 2, { "hello": "there" }]}',
124+
output: {
125+
key: [1, 2, { hello: 'there' }],
126+
},
127+
},
115128
]
116129

117130
for (const { input, output } of INPUT_AND_OUTPUT) {

pnpm-lock.yaml

Lines changed: 29 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)