From bfcd923793dfdf408dd3f8029a082f7dd97aa85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 7 Feb 2022 06:10:31 +0100 Subject: [PATCH] fix(docz-utils): fix closing tag detection in `removeTags` (#1696) --- core/docz-utils/.babelrc | 14 +++ core/docz-utils/__tests__/jsx.test.ts | 35 ++++++ core/docz-utils/package.json | 9 +- core/docz-utils/src/ast.ts | 10 +- core/docz-utils/src/jsx.ts | 20 +++- yarn.lock | 165 +++++++++++++++++++++++++- 6 files changed, 238 insertions(+), 15 deletions(-) create mode 100644 core/docz-utils/.babelrc create mode 100644 core/docz-utils/__tests__/jsx.test.ts diff --git a/core/docz-utils/.babelrc b/core/docz-utils/.babelrc new file mode 100644 index 000000000..ec5ca88ca --- /dev/null +++ b/core/docz-utils/.babelrc @@ -0,0 +1,14 @@ +{ + "plugins": ["lodash"], + "presets": [ + "@babel/preset-typescript", + [ + "@babel/preset-env", + { + "targets": { + "node": "current" + } + } + ] + ] +} diff --git a/core/docz-utils/__tests__/jsx.test.ts b/core/docz-utils/__tests__/jsx.test.ts new file mode 100644 index 000000000..29a5a79e3 --- /dev/null +++ b/core/docz-utils/__tests__/jsx.test.ts @@ -0,0 +1,35 @@ +import { removeTags } from '../src/jsx' + +describe('removeTags', () => { + test('removes outer JSX tag', () => { + expect( + removeTags(` + +
Some text
+

Other text

+
+ `) + ).toMatchInlineSnapshot(` + " +
Some text
+

Other text

+ " + `) + }) + + test('works when the closing tag is repeated in a comment', () => { + expect( + removeTags(` + + {/* */} +
Some text
+ + `) + ).toMatchInlineSnapshot(` + " + {/* */} +
Some text
+ " + `) + }) +}) diff --git a/core/docz-utils/package.json b/core/docz-utils/package.json index 612dc78db..7a237d0ed 100644 --- a/core/docz-utils/package.json +++ b/core/docz-utils/package.json @@ -21,12 +21,13 @@ "build": "trash lib && cross-env NODE_ENV=production rollup -c", "fix": "yarn lint --fix", "lint": "eslint . --ext mdx,ts,tsx", - "precommit": "lint-staged" + "precommit": "lint-staged", + "test": "yarn jest" }, "dependencies": { - "@babel/generator": "^7.5.5", - "@babel/parser": "^7.5.5", - "@babel/traverse": "^7.5.5", + "@babel/generator": "^7.16.8", + "@babel/parser": "^7.16.12", + "@babel/traverse": "^7.16.10", "art-template": "^4.13.2", "fs-extra": "^8.1.0", "humanize-string": "^2.1.0", diff --git a/core/docz-utils/src/ast.ts b/core/docz-utils/src/ast.ts index d88609c97..d319812fd 100644 --- a/core/docz-utils/src/ast.ts +++ b/core/docz-utils/src/ast.ts @@ -2,13 +2,13 @@ import * as parser from '@babel/parser' import traverse from '@babel/traverse' type Condition = (path: any) => boolean -type Predicate = (path: any) => any +type Predicate = (path: any) => Value -export const valueFromTraverse = ( +export const valueFromTraverse = ( condition: Condition, - predicate: Predicate = p => p -) => (code: string) => { - let value = '' + predicate: Predicate = p => p +) => (code: string): Value | '' => { + let value: Value | '' = '' const ast = parser.parse(code, { plugins: ['jsx'] }) traverse(ast, { diff --git a/core/docz-utils/src/jsx.ts b/core/docz-utils/src/jsx.ts index a6bb08e44..9d78919ef 100644 --- a/core/docz-utils/src/jsx.ts +++ b/core/docz-utils/src/jsx.ts @@ -2,7 +2,7 @@ import * as jsxUtils from 'jsx-ast-utils' import strip from 'strip-indent' import escapeJS from 'js-string-escape' -import { valueFromTraverse, codeFromNode } from './ast' +import { valueFromTraverse } from './ast' export const propFromElement = (prop: string) => valueFromTraverse( @@ -10,11 +10,21 @@ export const propFromElement = (prop: string) => p => jsxUtils.getPropValue(jsxUtils.getProp(p.node.attributes, prop)) ) -export const removeTags = (code: string) => { - const open = codeFromNode(p => p.isJSXOpeningElement()) - const close = codeFromNode(p => p.isJSXClosingElement()) +const getTagContentsRange = valueFromTraverse<[number, number] | null>( + p => p.isJSXElement(), + ({ node }) => { + if (!node.closingElement) { + // if the JSX element doesn't have a closingElement, it's because it's self-closed + // and thus does not have any content: + return null + } + return [node.openingElement.end, node.closingElement.start] + } +) - return code.replace(open(code), '').replace(close(code), '') +export const removeTags = (code: string) => { + const [start, end] = getTagContentsRange(code) || [0, 0] + return code.slice(start, end) } export const sanitizeCode = (code: string) => { diff --git a/yarn.lock b/yarn.lock index 3ee71449f..21d6b8190 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,6 +26,13 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -154,6 +161,15 @@ lodash "^4.17.13" source-map "^0.5.0" +"@babel/generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== + dependencies: + "@babel/types" "^7.16.8" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/generator@^7.9.0": version "7.9.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" @@ -290,6 +306,13 @@ "@babel/types" "^7.8.3" lodash "^4.17.13" +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-explode-assignable-expression@^7.1.0": version "7.1.0" resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" @@ -315,6 +338,15 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-function-name@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" @@ -331,6 +363,13 @@ dependencies: "@babel/types" "^7.0.0" +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-get-function-arity@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" @@ -338,6 +377,13 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-hoist-variables@^7.4.4": version "7.4.4" resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" @@ -513,6 +559,13 @@ "@babel/template" "^7.8.3" "@babel/types" "^7.8.3" +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-split-export-declaration@^7.4.0", "@babel/helper-split-export-declaration@^7.4.4": version "7.4.4" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" @@ -532,6 +585,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + "@babel/helper-validator-identifier@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" @@ -584,6 +642,15 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/highlight@^7.8.3": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" @@ -598,6 +665,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81" integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A== +"@babel/parser@^7.16.10", "@babel/parser@^7.16.12", "@babel/parser@^7.16.7": + version "7.16.12" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" + integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== + "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": version "7.9.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" @@ -1925,6 +1997,15 @@ "@babel/parser" "^7.6.0" "@babel/types" "^7.6.0" +"@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" @@ -1949,6 +2030,22 @@ globals "^11.1.0" lodash "^4.17.13" +"@babel/traverse@^7.16.10": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" + integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.10" + "@babel/types" "^7.16.8" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" @@ -1982,6 +2079,14 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.16.7", "@babel/types@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" + integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" @@ -8832,6 +8937,29 @@ docz-core@^1.2.0: ws "^7.0.0" yargs "^13.2.2" +docz-rollup@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/docz-rollup/-/docz-rollup-2.1.0.tgz#b3480fc64d0c0ec052f6e31dba99fd819e5a79f5" + integrity sha512-Pxhz0dYeT4WZ1QdRTmVwXQy3sP8iQHBWJB8SE2KnCa2n6LsQb/dwqqBwmyEf/xsS9PmG9t4iGZBY9OmVy6gzjg== + dependencies: + chalk "^2.4.2" + figures "3.0.0" + filesize "^4.1.2" + fs-extra "^8.1.0" + gzip-size "^5.1.1" + lodash "^4.17.14" + log-update "^3.2.0" + rollup "^1.17.0" + rollup-plugin-alias "^1.5.2" + rollup-plugin-babel "^4.3.3" + rollup-plugin-commonjs "^10.0.1" + rollup-plugin-json "^4.0.0" + rollup-plugin-node-resolve "^5.2.0" + rollup-plugin-peer-deps-external "^2.2.0" + rollup-plugin-postcss "^2.0.3" + rollup-plugin-progress "^1.1.1" + rollup-plugin-typescript2 "^0.22.0" + docz-utils@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/docz-utils/-/docz-utils-1.2.0.tgz#a7e9f3f56217f17fbc0699b5f4cf4323a53f3d13" @@ -9314,6 +9442,31 @@ escodegen@^1.8.1, escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-docz-js@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-docz-js/-/eslint-config-docz-js-2.1.0.tgz#358f97cd27099462f7c66fde842f52cb634a8fe0" + integrity sha512-72s9brNYxArHS6hI6Obh6owbanenHb6jMHVR/3t6zEj+U8oZH/1zuJNBD4RMO3X9XZ3FrLXrdGV4IFKzaM0OdQ== + dependencies: + babel-eslint "^10.0.2" + eslint "^6.5.1" + eslint-config-prettier "^5.0.0" + eslint-plugin-mdx "^1.6.1" + eslint-plugin-prettier "^3.1.0" + eslint-plugin-react "^7.13.0" + +eslint-config-docz-ts@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-docz-ts/-/eslint-config-docz-ts-2.1.0.tgz#54a36ab45ba88e862d484e863a9164858c14484a" + integrity sha512-gm14cE/cyeqWzaDWMyWLgaMOJzhNat+hqPTXjDuC93vPNJBjXjwn/txplOB1rkQX6ke1TTrkWE/AgvsNVYbraw== + dependencies: + "@typescript-eslint/eslint-plugin" "^1.12.0" + "@typescript-eslint/parser" "^1.12.0" + eslint "^6.5.1" + eslint-config-prettier "^5.0.0" + eslint-plugin-mdx "^1.6.1" + eslint-plugin-prettier "^3.1.0" + eslint-plugin-react "^7.13.0" + eslint-config-kentcdodds@^14.3.2: version "14.3.2" resolved "https://registry.npmjs.org/eslint-config-kentcdodds/-/eslint-config-kentcdodds-14.3.2.tgz#82428a350fd74c22b3dd0682786f87ad29e08c1d" @@ -18011,6 +18164,16 @@ remark-docz@^1.2.0: unist-util-remove "^1.0.1" unist-util-visit "^1.4.0" +remark-docz@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/remark-docz/-/remark-docz-2.1.0.tgz#e5ea97ec1922689d6fcd9965d49ae36162709eb3" + integrity sha512-5Crfi0xyBEoEJP06eaVZ6FodMWf3SunzL8icubxxqgAaIklgqp9H2hQ6getSe+0VM8yj0P1r2LPrl7GA1PLEPw== + dependencies: + "@babel/generator" "^7.5.5" + "@babel/types" "^7.5.5" + unist-util-remove "^1.0.3" + unist-util-visit "^1.4.1" + remark-frontmatter@^1.3.1, remark-frontmatter@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.3.2.tgz#91d9684319cd1b96cc3d9d901f10a978f39c752d" @@ -18565,7 +18728,7 @@ rollup-plugin-postcss@^2.0.3: rollup-pluginutils "^2.0.1" style-inject "^0.3.0" -rollup-plugin-progress@^1.1.2: +rollup-plugin-progress@^1.1.1, rollup-plugin-progress@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/rollup-plugin-progress/-/rollup-plugin-progress-1.1.2.tgz#5c1dfe7c50f654906bc34d167d5512ee1a4b72d5" integrity sha512-6ehSZOMTZdAlRpe45kf56BnIOsDYC2GKWhGlK/Dh/Ae/AMUneMDyKdiv9ZlRrW/HVc986frTZcc2Zka+oF6W7Q==