fix(mdx): Handle brace counting correctly inside strings for Next-MDX-Remote data props parsing
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🧪 QA (push) Successful in 1m13s
Build & Deploy / 🏗️ Build (push) Successful in 2m31s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🔔 Notify (push) Successful in 3s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m18s
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🧪 QA (push) Successful in 1m13s
Build & Deploy / 🏗️ Build (push) Successful in 2m31s
Build & Deploy / 🚀 Deploy (push) Successful in 16s
Build & Deploy / 🔔 Notify (push) Successful in 3s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m18s
This commit is contained in:
@@ -7,14 +7,36 @@ export function fixMdxDataProps(content: string): string {
|
|||||||
let endIndex = -1;
|
let endIndex = -1;
|
||||||
const startObj = dataIndex + 6; // index of the first '{' in 'data={{'
|
const startObj = dataIndex + 6; // index of the first '{' in 'data={{'
|
||||||
|
|
||||||
|
let inString = false;
|
||||||
|
let isEscaped = false;
|
||||||
|
|
||||||
for (let i = startObj; i < fixedContent.length; i++) {
|
for (let i = startObj; i < fixedContent.length; i++) {
|
||||||
if (fixedContent[i] === '{') {
|
const char = fixedContent[i];
|
||||||
openCount++;
|
|
||||||
} else if (fixedContent[i] === '}') {
|
if (isEscaped) {
|
||||||
openCount--;
|
isEscaped = false;
|
||||||
if (openCount === 0) {
|
continue;
|
||||||
endIndex = i;
|
}
|
||||||
break;
|
|
||||||
|
if (char === '\\') {
|
||||||
|
isEscaped = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char === '"') {
|
||||||
|
inString = !inString;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inString) {
|
||||||
|
if (char === '{') {
|
||||||
|
openCount++;
|
||||||
|
} else if (char === '}') {
|
||||||
|
openCount--;
|
||||||
|
if (openCount === 0) {
|
||||||
|
endIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"preinstall": "npx only-allow pnpm"
|
"preinstall": "npx only-allow pnpm"
|
||||||
},
|
},
|
||||||
"version": "2.3.30",
|
"version": "2.3.31",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@parcel/watcher",
|
"@parcel/watcher",
|
||||||
|
|||||||
@@ -8,10 +8,15 @@ describe('MDX Data Props Fixer', () => {
|
|||||||
|
|
||||||
const result = fixMdxDataProps(mdxInput);
|
const result = fixMdxDataProps(mdxInput);
|
||||||
|
|
||||||
// The expected output should have the entire JSON object enclosed in data="{...}"
|
|
||||||
// and NO trailing characters left over from the regex truncating early.
|
|
||||||
const expected = `<Block type="productTabs" data="{"content":{"root":{"children":[]}},"id":"123"}" />`;
|
const expected = `<Block type="productTabs" data="{"content":{"root":{"children":[]}},"id":"123"}" />`;
|
||||||
|
|
||||||
expect(result).toBe(expected);
|
expect(result).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not prematurely truncate if } appears inside a string literal', () => {
|
||||||
|
const mdxInput = `<Block type="productTabs" data={{"content":{"text":"}>"}}} />`;
|
||||||
|
const result = fixMdxDataProps(mdxInput);
|
||||||
|
const expected = `<Block type="productTabs" data="{"content":{"text":"}>"}}" />`;
|
||||||
|
expect(result).toBe(expected.replace('>', '>'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user