diff --git a/admin/scripts/generateExamples.mjs b/admin/scripts/generateExamples.mjs index e47b6b080b..ae1bd3e9df 100644 --- a/admin/scripts/generateExamples.mjs +++ b/admin/scripts/generateExamples.mjs @@ -92,9 +92,9 @@ async function generateTemplateExample(template) { ); console.log(`Generated example for template ${template}`); - } catch (error) { + } catch (err) { console.error(`Failed to generated example for template ${template}`); - throw error; + throw err; } } @@ -115,12 +115,12 @@ function updateStarters() { console.log(`forcePushGitSubtree command: ${command}`); shell.exec(command); console.log('forcePushGitSubtree success!'); - } catch (e) { + } catch (err) { console.error( `Can't force push to git subtree with command '${command}'`, ); console.error(`If it's a permission problem, ask @slorber`); - console.error(e); + console.error(err); } console.log(''); } diff --git a/jest.config.mjs b/jest.config.mjs index 9bd06327ae..fa508a5fcb 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -53,4 +53,5 @@ export default { location: {href: 'https://docusaurus.io'}, }, }, + snapshotSerializers: ['/jest/snapshotPathNormalizer.js'], }; diff --git a/jest/snapshotPathNormalizer.js b/jest/snapshotPathNormalizer.js new file mode 100644 index 0000000000..e97e034231 --- /dev/null +++ b/jest/snapshotPathNormalizer.js @@ -0,0 +1,174 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* eslint-disable import/no-extraneous-dependencies */ + +// Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js +// Added some project-specific handlers + +const _ = require('lodash'); +const {escapePath} = require('@docusaurus/utils'); +const os = require('os'); +const path = require('path'); +const fs = require('fs'); + +module.exports = { + print(val, serialize) { + let normalizedValue = val; + + if (_.isError(normalizedValue)) { + const message = normalizePaths(normalizedValue.message); + const error = new Error(message); + + // Clone hidden props + const ownProps = Object.getOwnPropertyNames(error); + // eslint-disable-next-line no-restricted-syntax + for (const index in ownProps) { + if (Object.prototype.hasOwnProperty.call(ownProps, index)) { + const key = ownProps[index]; + + error[key] = normalizePaths(normalizedValue[key]); + } + } + + // Clone normal props + // eslint-disable-next-line no-restricted-syntax + for (const index in normalizedValue) { + if (Object.prototype.hasOwnProperty.call(normalizedValue, index)) { + error[index] = normalizePaths(normalizedValue[index]); + } + } + + normalizedValue = error; + } else if (typeof normalizedValue === 'object') { + normalizedValue = _.cloneDeep(normalizedValue); + + Object.keys(normalizedValue).forEach((key) => { + normalizedValue[key] = normalizePaths(normalizedValue[key]); + }); + } else { + normalizedValue = normalizePaths(normalizedValue); + } + + return serialize(normalizedValue); + }, + test(val) { + let has = false; + + if (val && typeof val === 'object') { + // val.message is non-enumerable in an error + if (val.message && shouldUpdate(val.message)) { + has = true; + } + + Object.keys(val).forEach((key) => { + if (shouldUpdate(val[key])) { + has = true; + } + }); + } else if (shouldUpdate(val)) { + has = true; + } + + return has; + }, + normalizePaths, + getRealPath, +}; + +/** + * Normalize paths across platforms. + * Filters must be ran on all platforms to guard against false positives + */ +function normalizePaths(value) { + if (typeof value !== 'string') { + return value; + } + + const cwd = process.cwd(); + const cwdReal = getRealPath(cwd); + const tempDir = os.tmpdir(); + const tempDirReal = getRealPath(tempDir); + const homeDir = os.homedir(); + const homeDirReal = getRealPath(homeDir); + + const homeRelativeToTemp = path.relative(tempDir, homeDir); + const homeRelativeToTempReal = path.relative(tempDirReal, homeDir); + const homeRealRelativeToTempReal = path.relative(tempDirReal, homeDirReal); + const homeRealRelativeToTemp = path.relative(tempDir, homeDirReal); + + const runner = [ + // Replace process.cwd with + (val) => val.split(cwdReal).join(''), + (val) => val.split(cwd).join(''), + + // Replace home directory with + (val) => val.split(tempDirReal).join(''), + (val) => val.split(tempDir).join(''), + + // Replace home directory with + (val) => val.split(homeDirReal).join(''), + (val) => val.split(homeDir).join(''), + + // handle HOME_DIR nested inside TEMP_DIR + (val) => + val + .split(`${path.sep + homeRelativeToTemp}`) + .join(''), + (val) => + val + .split(`${path.sep + homeRelativeToTempReal}`) + .join(''), // untested + (val) => + val + .split(`${path.sep + homeRealRelativeToTempReal}`) + .join(''), + (val) => + val + .split(`${path.sep + homeRealRelativeToTemp}`) + .join(''), // untested + + // In case the CWD is escaped + (val) => val.split(escapePath(cwd)).join(''), + + // Remove win32 drive letters, C:\ -> \ + (val) => val.replace(/[a-zA-Z]:\\/g, '\\'), + + // Remove duplicate backslashes created from escapePath + (val) => val.replace(/\\\\/g, '\\'), + + // Convert win32 backslash's to forward slashes, \ -> /; + // ignore some that look like escape sequences. + (val) => val.replace(/\\(?!["])/g, '/'), + ]; + + let result = value; + runner.forEach((current) => { + result = current(result); + }); + + return result; +} + +function shouldUpdate(value) { + if (typeof value !== 'string') { + return false; + } + + // return true if value is different from normalized value + return normalizePaths(value) !== value; +} + +function getRealPath(pathname) { + try { + // eslint-disable-next-line no-restricted-properties + const realPath = fs.realpathSync(pathname); + + return realPath; + } catch (error) { + return pathname; + } +} diff --git a/packages/docusaurus-mdx-loader/src/index.ts b/packages/docusaurus-mdx-loader/src/index.ts index 98690e146a..7a704ef847 100644 --- a/packages/docusaurus-mdx-loader/src/index.ts +++ b/packages/docusaurus-mdx-loader/src/index.ts @@ -58,10 +58,9 @@ type Options = RemarkAndRehypePluginOptions & { async function readMetadataPath(metadataPath: string) { try { return await fs.readFile(metadataPath, 'utf8'); - } catch (e) { - throw new Error( - `MDX loader can't read MDX metadata file for path ${metadataPath}. Maybe the isMDXPartial option function was not provided?`, - ); + } catch (err) { + logger.error`MDX loader can't read MDX metadata file path=${metadataPath}. Maybe the isMDXPartial option function was not provided?`; + throw err; } } diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/inline-code.md b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/inline-code.md index 6198b3a2eb..0136c79977 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/inline-code.md +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__fixtures__/inline-code.md @@ -7,3 +7,5 @@ ## `
Test
` ## `
Test
` + +## [`
Test
`](/some/link) diff --git a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap index bca8c59199..f82cda96d3 100644 --- a/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/toc/__tests__/__snapshots__/index.test.ts.snap @@ -26,6 +26,11 @@ exports[`inline code should be escaped 1`] = ` value: '<div><i>Test</i></div>', id: 'divitestidiv', level: 2 + }, + { + value: '<div><i>Test</i></div>', + id: 'divitestidiv-1', + level: 2 } ]; @@ -38,6 +43,8 @@ exports[`inline code should be escaped 1`] = ` ## \`
Test
\` ## \`
Test
\` + +## [\`
Test
\`](/some/link) " `; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/invalid-img.md b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/invalid-img.md new file mode 100644 index 0000000000..a41a28b708 --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/invalid-img.md @@ -0,0 +1 @@ +![invalid image](/invalid.png) diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/invalid.png b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/invalid.png new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap index 086a8041c5..929b9125f4 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.ts.snap @@ -1,5 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`transformImage plugin does not choke on invalid image 1`] = ` +"{\\"invalid/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/invalid.png\\").default} /> +" +`; + exports[`transformImage plugin fail if image does not exist 1`] = `"Image packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static/img/doesNotExist.png or packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/static2/img/doesNotExist.png used in packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/fail.md not found."`; exports[`transformImage plugin fail if image relative path does not exist 1`] = `"Image packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/notFound.png used in packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__fixtures__/fail2.md not found."`; @@ -14,27 +19,27 @@ exports[`transformImage plugin pathname protocol 1`] = ` exports[`transformImage plugin transform md images to 1`] = ` "![img](https://example.com/img.png) - +/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> -{\\"img\\"} +{\\"img\\"}/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" /> -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" /> -{\\"img\\"} {\\"img\\"} +{\\"img\\"}/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"Title\\" width=\\"200\\" height=\\"200\\" /> {\\"img\\"}/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"'Quoted' title\\" width=\\"200\\" height=\\"200\\" /> -{\\"site +{\\"site/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> -{\\"img -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#light'} width=\\"200\\" height=\\"200\\" /> +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#dark'} width=\\"200\\" height=\\"200\\" /> -{\\"img -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10\\").default} width=\\"200\\" height=\\"200\\" /> +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default} width=\\"200\\" height=\\"200\\" /> -{\\"img +{\\"img/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default + '#light'} width=\\"200\\" height=\\"200\\" /> ## Heading diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts index e56fe47c19..90cb4fb15b 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/index.test.ts @@ -21,10 +21,7 @@ const processFixture = async (name, options) => { .use(plugin, {...options, filePath}) .process(file); - return result - .toString() - .replace(/\\\\/g, '/') - .replace(new RegExp(process.cwd().replace(/\\/g, '/'), 'g'), '[CWD]'); + return result.toString(); }; const staticDirs = [ @@ -60,4 +57,11 @@ describe('transformImage plugin', () => { const result = await processFixture('pathname', {staticDirs}); expect(result).toMatchSnapshot(); }); + + test('does not choke on invalid image', async () => { + const errorMock = jest.spyOn(console, 'error').mockImplementation(); + const result = await processFixture('invalid-img', {staticDirs}); + expect(result).toMatchSnapshot(); + expect(errorMock).toBeCalledTimes(1); + }); }); diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts index 5bb0ae6210..c5ed71492e 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts @@ -66,9 +66,9 @@ async function toImageRequireNode( if (size.height) { height = ` height="${size.height}"`; } - } catch (e) { + } catch (err) { logger.error`The image at path=${imagePath} can't be read correctly. Please ensure it's a valid image. -${(e as Error).message}`; +${(err as Error).message}`; } Object.keys(jsxNode).forEach( diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.ts.snap index 7f21f6948a..e64a76c275 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.ts.snap @@ -12,13 +12,13 @@ exports[`transformAsset plugin pathname protocol 1`] = ` exports[`transformAsset plugin transform md links to 1`] = ` "[asset](https://example.com/asset.pdf) - +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}> -asset +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset -asset with hash +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default + '#page=2'}>asset with hash -asset +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default} title=\\"Title\\">asset [page](noUrl.md) @@ -32,24 +32,24 @@ exports[`transformAsset plugin transform md links to 1`] = ` [assets](/github/!file-loader!/assets.pdf) -asset +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset -asset2 +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static2/asset2.pdf').default}>asset2 -staticAsset.pdf +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>staticAsset.pdf -@site/static/staticAsset.pdf +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>@site/static/staticAsset.pdf -@site/static/staticAsset.pdf +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default + '#page=2'} title=\\"Title\\">@site/static/staticAsset.pdf -Just staticAsset.pdf, and awesome staticAsset 2.pdf 'It is really "AWESOME"', but also coded staticAsset 3.pdf +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>Just staticAsset.pdf, and /node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>awesome staticAsset 2.pdf 'It is really "AWESOME"', but also /node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>coded staticAsset 3.pdf -{\\"Clickable +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAssetImage.png').default}>{\\"Clickable/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=/node_modules/file-loader/dist/cjs.js!./static/staticAssetImage.png\\").default} width=\\"200\\" height=\\"200\\" /> -Stylized link to asset file +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>Stylized link to asset file -json +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./data.json').default}>json -static json +/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticjson.json').default}>static json " `; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts index a1bf18ceb3..2b2ac7979d 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.ts @@ -30,10 +30,7 @@ const processFixture = async (name: string, options?) => { }) .process(file); - return result - .toString() - .replace(/\\\\/g, '/') - .replace(new RegExp(process.cwd().replace(/\\/g, '/'), 'g'), '[CWD]'); + return result.toString(); }; describe('transformAsset plugin', () => { diff --git a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts index 29beb5a1d5..e735eea28e 100644 --- a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts @@ -11,7 +11,7 @@ import type {Parent} from 'unist'; import type {PhrasingContent, Heading} from 'mdast'; export function stringifyContent(node: Parent): string { - return ((node.children || []) as PhrasingContent[]).map(toValue).join(''); + return (node.children as PhrasingContent[]).map(toValue).join(''); } export function toValue(node: PhrasingContent | Heading): string { diff --git a/packages/docusaurus-migrate/src/__tests__/__snapshots__/migration.test.ts.snap b/packages/docusaurus-migrate/src/__tests__/__snapshots__/migration.test.ts.snap new file mode 100644 index 0000000000..2c3e1ad0f0 --- /dev/null +++ b/packages/docusaurus-migrate/src/__tests__/__snapshots__/migration.test.ts.snap @@ -0,0 +1,592 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`migration test complex website: copy 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/static", + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/static", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/blog", + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/blog", + ], +] +`; + +exports[`migration test complex website: mkdirp 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages/", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/css", + ], +] +`; + +exports[`migration test complex website: mkdirs 1`] = `Array []`; + +exports[`migration test complex website: write 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages/index.js", + "import Layout from \\"@theme/Layout\\"; + import React from \\"react\\"; + + export default () => { + return ; + }; + ", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/css/customTheme.css", + ":root{ + --ifm-color-primary-lightest: #3CAD6E; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-light: #33925D; + --ifm-color-primary: #2E8555; + --ifm-color-primary-dark: #29784C; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205D3B; +} +", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/docusaurus.config.js", + "module.exports={ + \\"title\\": \\"Docusaurus\\", + \\"tagline\\": \\"Easy to Maintain Open Source Documentation Websites\\", + \\"url\\": \\"https://docusaurus.io\\", + \\"baseUrl\\": \\"/\\", + \\"organizationName\\": \\"facebook\\", + \\"projectName\\": \\"docusaurus\\", + \\"noIndex\\": false, + \\"scripts\\": [ + \\"https://buttons.github.io/buttons.js\\", + \\"https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js\\", + \\"/js/code-blocks-buttons.js\\" + ], + \\"favicon\\": \\"img/docusaurus.ico\\", + \\"customFields\\": { + \\"users\\": { + \\"caption\\": \\"DevSpace\\", + \\"image\\": \\"/img/users/devspace.svg\\", + \\"infoLink\\": \\"https://devspace.cloud/docs/\\", + \\"fbOpenSource\\": false, + \\"pinned\\": false + }, + \\"translationRecruitingLink\\": \\"https://crowdin.com/project/docusaurus\\", + \\"facebookAppId\\": \\"199138890728411\\" + }, + \\"onBrokenLinks\\": \\"log\\", + \\"onBrokenMarkdownLinks\\": \\"log\\", + \\"presets\\": [ + [ + \\"@docusaurus/preset-classic\\", + { + \\"docs\\": { + \\"showLastUpdateAuthor\\": true, + \\"showLastUpdateTime\\": true, + \\"editUrl\\": \\"https://github.com/facebook/docusaurus/edit/main/docs/\\" + }, + \\"blog\\": {}, + \\"theme\\": { + \\"customCss\\": \\"../complex_website/src/css/customTheme.css\\" + }, + \\"googleAnalytics\\": { + \\"trackingID\\": \\"UA-44373548-31\\" + } + } + ] + ], + \\"plugins\\": [], + \\"themeConfig\\": { + \\"navbar\\": { + \\"title\\": \\"Docusaurus\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus.svg\\" + }, + \\"items\\": [ + { + \\"to\\": \\"docs/installation\\", + \\"label\\": \\"Docs\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"docs/tutorial-setup\\", + \\"label\\": \\"Tutorial\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"/users\\", + \\"label\\": \\"Users\\", + \\"position\\": \\"left\\" + }, + { + \\"href\\": \\"https://github.com/facebook/docusaurus\\", + \\"label\\": \\"GitHub\\", + \\"position\\": \\"left\\" + } + ] + }, + \\"image\\": \\"img/docusaurus.png\\", + \\"footer\\": { + \\"links\\": [ + { + \\"title\\": \\"Community\\", + \\"items\\": [ + { + \\"label\\": \\"Twitter\\", + \\"to\\": \\"https://twitter.com/docusaurus\\" + } + ] + } + ], + \\"copyright\\": \\"Copyright © 2022 Facebook Inc.\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus_monochrome.svg\\" + } + }, + \\"algolia\\": { + \\"apiKey\\": \\"3eb9507824b8be89e7a199ecaa1a9d2c\\", + \\"indexName\\": \\"docusaurus\\", + \\"algoliaOptions\\": { + \\"facetFilters\\": [ + \\"language:LANGUAGE\\", + \\"version:VERSION\\" + ] + } + } + } +}", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/package.json", + "{ + \\"name\\": \\"docusaurus-1-website\\", + \\"version\\": \\"2.0.0-alpha.58\\", + \\"private\\": true, + \\"scripts\\": { + \\"start\\": \\"docusaurus start\\", + \\"build\\": \\"docusaurus build\\", + \\"publish-gh-pages\\": \\"docusaurus-publish\\", + \\"examples\\": \\"docusaurus-examples\\", + \\"write-translations\\": \\"docusaurus-write-translations\\", + \\"docusaurus-version\\": \\"docusaurus-version\\", + \\"rename-version\\": \\"docusaurus-rename-version\\", + \\"crowdin-upload\\": \\"crowdin --config ../crowdin.yaml upload sources --auto-update -b master\\", + \\"crowdin-download\\": \\"crowdin --config ../crowdin.yaml download -b master\\", + \\"swizzle\\": \\"docusaurus swizzle\\", + \\"deploy\\": \\"docusaurus deploy\\", + \\"docusaurus\\": \\"docusaurus\\" + }, + \\"dependencies\\": { + \\"@docusaurus/core\\": \\"2.0.0-beta.15\\", + \\"@docusaurus/preset-classic\\": \\"2.0.0-beta.15\\", + \\"clsx\\": \\"^1.1.1\\", + \\"react\\": \\"^17.0.2\\", + \\"react-dom\\": \\"^17.0.2\\" + } +}", + ], +] +`; + +exports[`migration test missing versions: copy 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/static", + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/static", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/blog", + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/blog", + ], +] +`; + +exports[`migration test missing versions: mkdirp 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages/", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/css", + ], +] +`; + +exports[`migration test missing versions: mkdirs 1`] = `Array []`; + +exports[`migration test missing versions: write 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages/index.js", + "import Layout from \\"@theme/Layout\\"; + import React from \\"react\\"; + + export default () => { + return ; + }; + ", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/css/customTheme.css", + ":root{ + --ifm-color-primary-lightest: #3CAD6E; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-light: #33925D; + --ifm-color-primary: #2E8555; + --ifm-color-primary-dark: #29784C; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205D3B; +} +", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/docusaurus.config.js", + "module.exports={ + \\"title\\": \\"Docusaurus\\", + \\"tagline\\": \\"Easy to Maintain Open Source Documentation Websites\\", + \\"url\\": \\"https://docusaurus.io\\", + \\"baseUrl\\": \\"/\\", + \\"organizationName\\": \\"facebook\\", + \\"projectName\\": \\"docusaurus\\", + \\"noIndex\\": false, + \\"scripts\\": [ + \\"https://buttons.github.io/buttons.js\\", + \\"https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js\\", + \\"/js/code-blocks-buttons.js\\" + ], + \\"favicon\\": \\"img/docusaurus.ico\\", + \\"customFields\\": { + \\"users\\": { + \\"caption\\": \\"DevSpace\\", + \\"image\\": \\"/img/users/devspace.svg\\", + \\"infoLink\\": \\"https://devspace.cloud/docs/\\", + \\"fbOpenSource\\": false, + \\"pinned\\": false + }, + \\"translationRecruitingLink\\": \\"https://crowdin.com/project/docusaurus\\", + \\"facebookAppId\\": \\"199138890728411\\" + }, + \\"onBrokenLinks\\": \\"log\\", + \\"onBrokenMarkdownLinks\\": \\"log\\", + \\"presets\\": [ + [ + \\"@docusaurus/preset-classic\\", + { + \\"docs\\": { + \\"showLastUpdateAuthor\\": true, + \\"showLastUpdateTime\\": true, + \\"editUrl\\": \\"https://github.com/facebook/docusaurus/edit/main/docs/\\" + }, + \\"blog\\": {}, + \\"theme\\": { + \\"customCss\\": \\"../missing_version_website/src/css/customTheme.css\\" + }, + \\"googleAnalytics\\": { + \\"trackingID\\": \\"UA-44373548-31\\" + } + } + ] + ], + \\"plugins\\": [], + \\"themeConfig\\": { + \\"navbar\\": { + \\"title\\": \\"Docusaurus\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus.svg\\" + }, + \\"items\\": [ + { + \\"to\\": \\"docs/installation\\", + \\"label\\": \\"Docs\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"docs/tutorial-setup\\", + \\"label\\": \\"Tutorial\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"/users\\", + \\"label\\": \\"Users\\", + \\"position\\": \\"left\\" + }, + { + \\"href\\": \\"https://github.com/facebook/docusaurus\\", + \\"label\\": \\"GitHub\\", + \\"position\\": \\"left\\" + } + ] + }, + \\"image\\": \\"img/docusaurus.png\\", + \\"footer\\": { + \\"links\\": [ + { + \\"title\\": \\"Community\\", + \\"items\\": [ + { + \\"label\\": \\"Twitter\\", + \\"to\\": \\"https://twitter.com/docusaurus\\" + } + ] + } + ], + \\"copyright\\": \\"Copyright © 2022 Facebook Inc.\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus_monochrome.svg\\" + } + }, + \\"algolia\\": { + \\"apiKey\\": \\"3eb9507824b8be89e7a199ecaa1a9d2c\\", + \\"indexName\\": \\"docusaurus\\", + \\"algoliaOptions\\": { + \\"facetFilters\\": [ + \\"language:LANGUAGE\\", + \\"version:VERSION\\" + ] + } + } + } +}", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/package.json", + "{ + \\"name\\": \\"docusaurus-1-website\\", + \\"version\\": \\"2.0.0-alpha.58\\", + \\"private\\": true, + \\"scripts\\": { + \\"start\\": \\"docusaurus start\\", + \\"build\\": \\"docusaurus build\\", + \\"publish-gh-pages\\": \\"docusaurus-publish\\", + \\"examples\\": \\"docusaurus-examples\\", + \\"write-translations\\": \\"docusaurus-write-translations\\", + \\"docusaurus-version\\": \\"docusaurus-version\\", + \\"rename-version\\": \\"docusaurus-rename-version\\", + \\"crowdin-upload\\": \\"crowdin --config ../crowdin.yaml upload sources --auto-update -b master\\", + \\"crowdin-download\\": \\"crowdin --config ../crowdin.yaml download -b master\\", + \\"swizzle\\": \\"docusaurus swizzle\\", + \\"deploy\\": \\"docusaurus deploy\\", + \\"docusaurus\\": \\"docusaurus\\" + }, + \\"dependencies\\": { + \\"@docusaurus/core\\": \\"2.0.0-beta.15\\", + \\"@docusaurus/preset-classic\\": \\"2.0.0-beta.15\\", + \\"clsx\\": \\"^1.1.1\\", + \\"react\\": \\"^17.0.2\\", + \\"react-dom\\": \\"^17.0.2\\" + } +}", + ], +] +`; + +exports[`migration test simple website: copy 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/website/static", + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/static", + ], +] +`; + +exports[`migration test simple website: mkdirp 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages/", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/css", + ], +] +`; + +exports[`migration test simple website: mkdirs 1`] = `Array []`; + +exports[`migration test simple website: write 1`] = ` +Array [ + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages/index.js", + "import Layout from \\"@theme/Layout\\"; + import React from \\"react\\"; + + export default () => { + return ; + }; + ", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-commands.md", + "--- +id: commands +title: CLI Commands +--- + +## Doc ", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-doc-markdown.md", + "--- +id: doc-markdown +title: Markdown Features +--- + +## Doc", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/css/customTheme.css", + ":root{ + --ifm-color-primary-lightest: #3CAD6E; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-light: #33925D; + --ifm-color-primary: #2E8555; + --ifm-color-primary-dark: #29784C; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205D3B; +} +", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/docusaurus.config.js", + "module.exports={ + \\"title\\": \\"Docusaurus\\", + \\"tagline\\": \\"Easy to Maintain Open Source Documentation Websites\\", + \\"url\\": \\"https://docusaurus.io\\", + \\"baseUrl\\": \\"/\\", + \\"organizationName\\": \\"facebook\\", + \\"projectName\\": \\"docusaurus\\", + \\"noIndex\\": false, + \\"scripts\\": [ + \\"https://buttons.github.io/buttons.js\\", + \\"https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js\\", + \\"/js/code-blocks-buttons.js\\" + ], + \\"favicon\\": \\"img/docusaurus.ico\\", + \\"customFields\\": { + \\"users\\": { + \\"caption\\": \\"DevSpace\\", + \\"image\\": \\"/img/users/devspace.svg\\", + \\"infoLink\\": \\"https://devspace.cloud/docs/\\", + \\"fbOpenSource\\": false, + \\"pinned\\": false + }, + \\"translationRecruitingLink\\": \\"https://crowdin.com/project/docusaurus\\", + \\"facebookAppId\\": \\"199138890728411\\" + }, + \\"onBrokenLinks\\": \\"log\\", + \\"onBrokenMarkdownLinks\\": \\"log\\", + \\"presets\\": [ + [ + \\"@docusaurus/preset-classic\\", + { + \\"docs\\": { + \\"showLastUpdateAuthor\\": true, + \\"showLastUpdateTime\\": true, + \\"editUrl\\": \\"https://github.com/facebook/docusaurus/edit/main/docs/\\", + \\"path\\": \\"../simple_website/docs\\" + }, + \\"blog\\": {}, + \\"theme\\": { + \\"customCss\\": \\"../simple_website/src/css/customTheme.css\\" + }, + \\"googleAnalytics\\": { + \\"trackingID\\": \\"UA-44373548-31\\" + } + } + ] + ], + \\"plugins\\": [], + \\"themeConfig\\": { + \\"navbar\\": { + \\"title\\": \\"Docusaurus\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus.svg\\" + }, + \\"items\\": [ + { + \\"to\\": \\"docs/installation\\", + \\"label\\": \\"Docs\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"docs/tutorial-setup\\", + \\"label\\": \\"Tutorial\\", + \\"position\\": \\"left\\" + }, + { + \\"to\\": \\"/users\\", + \\"label\\": \\"Users\\", + \\"position\\": \\"left\\" + }, + { + \\"href\\": \\"https://github.com/facebook/docusaurus\\", + \\"label\\": \\"GitHub\\", + \\"position\\": \\"left\\" + } + ] + }, + \\"image\\": \\"img/docusaurus.png\\", + \\"footer\\": { + \\"links\\": [ + { + \\"title\\": \\"Community\\", + \\"items\\": [ + { + \\"label\\": \\"Twitter\\", + \\"to\\": \\"https://twitter.com/docusaurus\\" + } + ] + } + ], + \\"copyright\\": \\"Copyright © 2022 Facebook Inc.\\", + \\"logo\\": { + \\"src\\": \\"img/docusaurus_monochrome.svg\\" + } + }, + \\"algolia\\": { + \\"apiKey\\": \\"3eb9507824b8be89e7a199ecaa1a9d2c\\", + \\"indexName\\": \\"docusaurus\\", + \\"algoliaOptions\\": { + \\"facetFilters\\": [ + \\"language:LANGUAGE\\", + \\"version:VERSION\\" + ] + } + } + } +}", + ], + Array [ + "/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/package.json", + "{ + \\"name\\": \\"docusaurus-1-website\\", + \\"version\\": \\"2.0.0-alpha.58\\", + \\"private\\": true, + \\"scripts\\": { + \\"start\\": \\"docusaurus start\\", + \\"build\\": \\"docusaurus build\\", + \\"publish-gh-pages\\": \\"docusaurus-publish\\", + \\"examples\\": \\"docusaurus-examples\\", + \\"write-translations\\": \\"docusaurus-write-translations\\", + \\"docusaurus-version\\": \\"docusaurus-version\\", + \\"rename-version\\": \\"docusaurus-rename-version\\", + \\"crowdin-upload\\": \\"crowdin --config ../crowdin.yaml upload sources --auto-update -b master\\", + \\"crowdin-download\\": \\"crowdin --config ../crowdin.yaml download -b master\\", + \\"swizzle\\": \\"docusaurus swizzle\\", + \\"deploy\\": \\"docusaurus deploy\\", + \\"docusaurus\\": \\"docusaurus\\" + }, + \\"dependencies\\": { + \\"@docusaurus/core\\": \\"2.0.0-beta.15\\", + \\"@docusaurus/preset-classic\\": \\"2.0.0-beta.15\\", + \\"clsx\\": \\"^1.1.1\\", + \\"react\\": \\"^17.0.2\\", + \\"react-dom\\": \\"^17.0.2\\" + } +}", + ], +] +`; diff --git a/packages/docusaurus-migrate/src/__tests__/migration.test.ts b/packages/docusaurus-migrate/src/__tests__/migration.test.ts index daf21ba47c..8709ad7f4d 100644 --- a/packages/docusaurus-migrate/src/__tests__/migration.test.ts +++ b/packages/docusaurus-migrate/src/__tests__/migration.test.ts @@ -9,53 +9,38 @@ import {migrateDocusaurusProject} from '../index'; import path from 'path'; import fs from 'fs-extra'; +async function testMigration(siteDir: string, newDir: string) { + const writeMock = jest.spyOn(fs, 'writeFile').mockImplementation(); + const mkdirpMock = jest.spyOn(fs, 'mkdirp').mockImplementation(); + const mkdirsMock = jest.spyOn(fs, 'mkdirs').mockImplementation(); + const copyMock = jest.spyOn(fs, 'copy').mockImplementation(); + await migrateDocusaurusProject(siteDir, newDir); + expect(writeMock.mock.calls).toMatchSnapshot('write'); + expect(mkdirpMock.mock.calls).toMatchSnapshot('mkdirp'); + expect(mkdirsMock.mock.calls).toMatchSnapshot('mkdirs'); + expect(copyMock.mock.calls).toMatchSnapshot('copy'); + writeMock.mockRestore(); + mkdirpMock.mockRestore(); + mkdirsMock.mockRestore(); + copyMock.mockRestore(); +} + describe('migration test', () => { + const fixtureDir = path.join(__dirname, '__fixtures__'); test('simple website', async () => { - const siteDir = path.join( - __dirname, - '__fixtures__', - 'simple_website', - 'website', - ); - const newDir = path.join(__dirname, '__fixtures__', 'migrated_simple_site'); - await expect( - migrateDocusaurusProject(siteDir, newDir), - ).resolves.toBeUndefined(); - await fs.remove(newDir); + const siteDir = path.join(fixtureDir, 'simple_website', 'website'); + const newDir = path.join(fixtureDir, 'migrated_simple_site'); + await testMigration(siteDir, newDir); }); test('complex website', async () => { - const siteDir = path.join( - __dirname, - '__fixtures__', - 'complex_website', - 'website', - ); - const newDir = path.join( - __dirname, - '__fixtures__', - 'migrated_complex_site', - ); - await expect( - migrateDocusaurusProject(siteDir, newDir), - ).resolves.toBeUndefined(); - await fs.remove(newDir); + const siteDir = path.join(fixtureDir, 'complex_website', 'website'); + const newDir = path.join(fixtureDir, 'migrated_complex_site'); + await testMigration(siteDir, newDir); }); test('missing versions', async () => { - const siteDir = path.join( - __dirname, - '__fixtures__', - 'missing_version_website', - 'website', - ); - const newDir = path.join( - __dirname, - '__fixtures__', - 'migrated_missing_version_site', - ); - await expect( - migrateDocusaurusProject(siteDir, newDir), - ).resolves.toBeUndefined(); - await fs.remove(newDir); + const siteDir = path.join(fixtureDir, 'missing_version_website', 'website'); + const newDir = path.join(fixtureDir, 'migrated_missing_version_site'); + await testMigration(siteDir, newDir); }); }); diff --git a/packages/docusaurus-migrate/src/frontMatter.ts b/packages/docusaurus-migrate/src/frontMatter.ts index ca07bcad6b..45e71c94a2 100644 --- a/packages/docusaurus-migrate/src/frontMatter.ts +++ b/packages/docusaurus-migrate/src/frontMatter.ts @@ -69,6 +69,7 @@ export function shouldQuotifyFrontMatter([key, value]: [ // TODO this is not ideal to have to maintain such a list of allowed chars // maybe we should quotify if gray-matter throws instead? return !String(value).match( + // cSpell:ignore sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ /^[\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$]+$/, ); } diff --git a/packages/docusaurus-migrate/src/index.ts b/packages/docusaurus-migrate/src/index.ts index dc16556a2c..4d1884038e 100644 --- a/packages/docusaurus-migrate/src/index.ts +++ b/packages/docusaurus-migrate/src/index.ts @@ -45,18 +45,22 @@ function sanitizedFileContent( migrateMDFiles: boolean, ): string { const extractedData = extractMetadata(content); - const extractedMetaData = Object.entries(extractedData.metadata).reduce( - (metaData, [key, value]) => - `${metaData}\n${key}: ${ - shouldQuotifyFrontMatter([key, value]) ? `"${value}"` : value - }`, - '', - ); - const sanitizedData = `---${extractedMetaData}\n---\n${ - migrateMDFiles - ? sanitizeMD(extractedData.rawContent) - : extractedData.rawContent - }`; + const extractedMetaData = Object.entries(extractedData.metadata) + .map( + ([key, value]) => + `${key}: ${ + shouldQuotifyFrontMatter([key, value]) ? `"${value}"` : value + }`, + ) + .join('\n'); + const sanitizedData = `--- +${extractedMetaData} +--- +${ + migrateMDFiles + ? sanitizeMD(extractedData.rawContent) + : extractedData.rawContent +}`; return sanitizedData; } @@ -106,8 +110,8 @@ export async function migrateDocusaurusProject( try { createClientRedirects(migrationContext); logger.success('Created client redirect for non clean URL'); - } catch (e) { - logger.error(`Failed to creating redirects: ${e}`); + } catch (err) { + logger.error(`Failed to creating redirects: ${err}`); errorCount += 1; } if (shouldMigratePages) { @@ -116,8 +120,8 @@ export async function migrateDocusaurusProject( logger.success( 'Created new doc pages (check migration page for more details)', ); - } catch (e) { - logger.error(`Failed to create new doc pages: ${e}`); + } catch (err) { + logger.error(`Failed to create new doc pages: ${err}`); errorCount += 1; } } else { @@ -126,8 +130,8 @@ export async function migrateDocusaurusProject( logger.success( 'Created landing page (check migration page for more details)', ); - } catch (e) { - logger.error(`Failed to create landing page: ${e}`); + } catch (err) { + logger.error(`Failed to create landing page: ${err}`); errorCount += 1; } } @@ -135,34 +139,34 @@ export async function migrateDocusaurusProject( try { await migrateStaticFiles(migrationContext); logger.success('Migrated static folder'); - } catch (e) { - logger.error(`Failed to copy static folder: ${e}`); + } catch (err) { + logger.error(`Failed to copy static folder: ${err}`); errorCount += 1; } try { await migrateBlogFiles(migrationContext); - } catch (e) { - logger.error(`Failed to migrate blogs: ${e}`); + } catch (err) { + logger.error(`Failed to migrate blogs: ${err}`); errorCount += 1; } try { await handleVersioning(migrationContext); - } catch (e) { - logger.error(`Failed to migrate versioned docs: ${e}`); + } catch (err) { + logger.error(`Failed to migrate versioned docs: ${err}`); errorCount += 1; } try { await migrateLatestDocs(migrationContext); - } catch (e) { - logger.error(`Failed to migrate docs: ${e}`); + } catch (err) { + logger.error(`Failed to migrate docs: ${err}`); errorCount += 1; } try { await migrateLatestSidebar(migrationContext); - } catch (e) { - logger.error(`Failed to migrate sidebar: ${e}`); + } catch (err) { + logger.error(`Failed to migrate sidebar: ${err}`); errorCount += 1; } @@ -174,15 +178,15 @@ export async function migrateDocusaurusProject( logger.success( `Created a new config file with new navbar and footer config`, ); - } catch (e) { - logger.error(`Failed to create config file: ${e}`); + } catch (err) { + logger.error(`Failed to create config file: ${err}`); errorCount += 1; } try { await migratePackageFile(migrationContext); - } catch (e) { + } catch (err) { logger.error( - `Error occurred while creating package.json file for project: ${e}`, + `Error occurred while creating package.json file for project: ${err}`, ); errorCount += 1; } @@ -387,8 +391,8 @@ async function createPages(context: MigrationContext) { await fs.writeFile(filePath, migratePage(content)); }), ); - } catch (e) { - logger.error(`Unable to migrate Pages: ${e}`); + } catch (err) { + logger.error(`Unable to migrate Pages: ${err}`); await createDefaultLandingPage(context); } } else { @@ -664,9 +668,7 @@ async function migrateLatestSidebar(context: MigrationContext) { await fs.writeFile(path.join(newDir, 'src', 'css', 'customTheme.css'), css); context.v2Config.presets[0][1].theme.customCss = path.join( path.relative(newDir, path.join(siteDir, '..')), - 'src', - 'css', - 'customTheme.css', + 'src/css/customTheme.css', ); } } diff --git a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts index de06a0b19e..6ffd68da51 100644 --- a/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts +++ b/packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts @@ -64,8 +64,8 @@ function validateCollectedRedirects( try { validateRedirect(redirect); return undefined; - } catch (e) { - return (e as Error).message; + } catch (err) { + return (err as Error).message; } }) .filter(Boolean); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/build-snap/blog/mdx-blog-post/index.html b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/build-snap/blog/mdx-blog-post/index.html index 921732b877..0b8cd0bbf4 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/build-snap/blog/mdx-blog-post/index.html +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__fixtures__/website/build-snap/blog/mdx-blog-post/index.html @@ -11,8 +11,7 @@
-

Full Blog Sample

· One min read

HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link -image

+

Full Blog Sample

· One min read

HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

linkimage

diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap index 28d2e5b294..228c9a76d1 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap @@ -26,8 +26,7 @@ Array [ 2021-03-05T00:00:00.000Z - HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link -\\"image\\"

]]>
+ HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link\\"image\\"

]]>
<![CDATA[Complex Slug]]> @@ -103,7 +102,7 @@ Array [ }, { \\"id\\": \\"/mdx-blog-post\\", - \\"content_html\\": \\"

HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link\\\\n\\\\\\"image\\\\\\"

\\", + \\"content_html\\": \\"

HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link\\\\\\"image\\\\\\"

\\", \\"url\\": \\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post\\", \\"title\\": \\"Full Blog Sample\\", \\"summary\\": \\"HTML Heading 1\\", @@ -197,8 +196,7 @@ Array [ /mdx-blog-post Fri, 05 Mar 2021 00:00:00 GMT - HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link -\\"image\\"

]]>
+ HTML Heading 1

HTML Heading 2

HTML Paragraph

Import DOM

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
  • list1
  • list2
  • list3
  • list1
  • list2
  • list3

Normal Text Italics Text Bold Text

link\\"image\\"

]]>
<![CDATA[Complex Slug]]> diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index 2c0eb4a630..1d788e5744 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -75,3 +75,64 @@ Object { }, } `; + +exports[`loadBlog test blog tags: no pagination 1`] = ` +Object { + "/blog/tags/tag-1": Object { + "items": Array [ + "/simple/slug/another", + "/another/tags", + "/another/tags2", + ], + "name": "tag1", + "pages": Array [ + Object { + "items": Array [ + "/simple/slug/another", + "/another/tags", + "/another/tags2", + ], + "metadata": Object { + "blogDescription": "Blog", + "blogTitle": "Blog", + "nextPage": null, + "page": 1, + "permalink": "/blog/tags/tag-1", + "postsPerPage": 3, + "previousPage": null, + "totalCount": 3, + "totalPages": 1, + }, + }, + ], + "permalink": "/blog/tags/tag-1", + }, + "/blog/tags/tag-2": Object { + "items": Array [ + "/another/tags", + "/another/tags2", + ], + "name": "tag2", + "pages": Array [ + Object { + "items": Array [ + "/another/tags", + "/another/tags2", + ], + "metadata": Object { + "blogDescription": "Blog", + "blogTitle": "Blog", + "nextPage": null, + "page": 1, + "permalink": "/blog/tags/tag-2", + "postsPerPage": 2, + "previousPage": null, + "totalCount": 2, + "totalPages": 1, + }, + }, + ], + "permalink": "/blog/tags/tag-2", + }, +} +`; diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogFrontMatter.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogFrontMatter.test.ts index bc3aaf174c..67ee71969f 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogFrontMatter.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogFrontMatter.test.ts @@ -54,9 +54,9 @@ function testField(params: { )}`, ), ); - } catch (e) { + } catch (err) { // eslint-disable-next-line jest/no-conditional-expect - expect(e.message).toMatch(new RegExp(escapeStringRegexp(message))); + expect(err.message).toMatch(new RegExp(escapeStringRegexp(message))); } }); }); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 200bb84432..6831584bb1 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -479,4 +479,17 @@ describe('loadBlog', () => { expect(Object.keys(blogTags).length).toEqual(2); expect(blogTags).toMatchSnapshot(); }); + + test('test blog tags: no pagination', async () => { + const siteDir = path.join( + __dirname, + '__fixtures__', + 'website-blog-with-tags', + ); + const blogTags = await getBlogTags(siteDir, { + postsPerPage: 'ALL', + }); + + expect(blogTags).toMatchSnapshot(); + }); }); diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 0cfaf0f146..6ae982b7b2 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -157,8 +157,9 @@ function formatBlogPostDate(locale: string, date: Date): string { year: 'numeric', timeZone: 'UTC', }).format(date); - } catch (e) { - throw new Error(`Can't format blog post date "${date}"`); + } catch (err) { + logger.error`Can't format blog post date "${String(date)}"`; + throw err; } } @@ -172,12 +173,9 @@ async function parseBlogPostMarkdownFile(blogSourceAbsolute: string) { ...result, frontMatter: validateBlogPostFrontMatter(result.frontMatter), }; - } catch (e) { - throw new Error( - `Error while parsing blog post file ${blogSourceAbsolute}: "${ - (e as Error).message - }".`, - ); + } catch (err) { + logger.error`Error while parsing blog post file path=${blogSourceAbsolute}.`; + throw err; } } @@ -246,8 +244,8 @@ async function processBlogSourceFile( includeAuthor: false, }); return result.date; - } catch (e) { - logger.error(e); + } catch (err) { + logger.error(err); return (await fs.stat(blogSourceAbsolute)).birthtime; } } @@ -357,9 +355,9 @@ export async function generateBlogPosts( options, authorsMap, ); - } catch (e) { - logger.error`Processing of blog source file failed for path path=${blogSourceFile}.`; - throw e; + } catch (err) { + logger.error`Processing of blog source file path=${blogSourceFile} failed.`; + throw err; } }), ) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts index e866f3099e..06edd9d6ee 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts @@ -73,8 +73,8 @@ describe('docsVersion', () => { DEFAULT_PLUGIN_ID, DEFAULT_OPTIONS, ), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`, + ).rejects.toThrowError( + '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.', ); await expect(() => cliDocsVersionCommand( @@ -83,8 +83,8 @@ describe('docsVersion', () => { DEFAULT_PLUGIN_ID, DEFAULT_OPTIONS, ), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`, + ).rejects.toThrowError( + '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.', ); }); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docFrontMatter.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docFrontMatter.test.ts index 7046cee91c..1a648a0eb6 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docFrontMatter.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docFrontMatter.test.ts @@ -51,9 +51,9 @@ function testField(params: { )}`, ), ); - } catch (e) { + } catch (err) { // eslint-disable-next-line jest/no-conditional-expect - expect(e.message).toMatch(new RegExp(escapeStringRegexp(message))); + expect(err.message).toMatch(new RegExp(escapeStringRegexp(message))); } }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index f00525b88e..ac0c372499 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -123,15 +123,13 @@ function createTestUtils({ async function generateNavigation( docFiles: DocFile[], ): Promise<[DocNavLink | undefined, DocNavLink | undefined][]> { - const rawDocs = await Promise.all( - docFiles.map((docFile) => - processDocMetadata({ - docFile, - versionMetadata, - context, - options, - }), - ), + const rawDocs = docFiles.map((docFile) => + processDocMetadata({ + docFile, + versionMetadata, + context, + options, + }), ); const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, { sidebarItemsGenerator: ({defaultSidebarItemsGenerator, ...args}) => diff --git a/packages/docusaurus-plugin-content-docs/src/docs.ts b/packages/docusaurus-plugin-content-docs/src/docs.ts index 4fd0d8a6e7..5e89dd53d8 100644 --- a/packages/docusaurus-plugin-content-docs/src/docs.ts +++ b/packages/docusaurus-plugin-content-docs/src/docs.ts @@ -275,9 +275,9 @@ export function processDocMetadata(args: { }): DocMetadataBase { try { return doProcessDocMetadata(args); - } catch (e) { + } catch (err) { logger.error`Can't process doc metadata for doc at path path=${args.docFile.filePath} in version name=${args.versionMetadata.versionName}`; - throw e; + throw err; } } diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index c8ccbab7e7..4e6d19f4bc 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -196,9 +196,9 @@ export default async function pluginContentDocs( async function loadVersion(versionMetadata: VersionMetadata) { try { return await doLoadVersion(versionMetadata); - } catch (e) { + } catch (err) { logger.error`Loading of version failed for version name=${versionMetadata.versionName}`; - throw e; + throw err; } } diff --git a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts index 9114bb3d9e..e62cfe3093 100644 --- a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts +++ b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts @@ -27,12 +27,12 @@ export async function getFileLastUpdate( includeAuthor: true, }); return {timestamp: result.timestamp, author: result.author}; - } catch (e) { - if (e instanceof GitNotFoundError && !showedGitRequirementError) { + } catch (err) { + if (err instanceof GitNotFoundError && !showedGitRequirementError) { logger.warn('Sorry, the docs plugin last update options require Git.'); showedGitRequirementError = true; } else { - logger.error(e); + logger.error(err); } return null; } diff --git a/packages/docusaurus-plugin-content-docs/src/routes.ts b/packages/docusaurus-plugin-content-docs/src/routes.ts index e86b42f571..ad7608f449 100644 --- a/packages/docusaurus-plugin-content-docs/src/routes.ts +++ b/packages/docusaurus-plugin-content-docs/src/routes.ts @@ -178,8 +178,8 @@ export async function createVersionRoutes({ try { return await doCreateVersionRoutes(loadedVersion); - } catch (e) { + } catch (err) { logger.error`Can't create version routes for version name=${loadedVersion.versionName}`; - throw e; + throw err; } } diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts index b57822b5dd..801a86dafd 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts @@ -61,9 +61,9 @@ async function readCategoriesMetadata(contentPath: string) { ); try { return validateCategoryMetadataFile(Yaml.load(content)); - } catch (e) { + } catch (err) { logger.error`The docs sidebar category metadata file path=${filePath} looks invalid!`; - throw e; + throw err; } }), ); diff --git a/packages/docusaurus-theme-common/src/utils/storageUtils.ts b/packages/docusaurus-theme-common/src/utils/storageUtils.ts index 6e5b49f3dd..cd03b64170 100644 --- a/packages/docusaurus-theme-common/src/utils/storageUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/storageUtils.ts @@ -26,8 +26,8 @@ function getBrowserStorage( } try { return window[storageType]; - } catch (e) { - logOnceBrowserStorageNotAvailableWarning(e as Error); + } catch (err) { + logOnceBrowserStorageNotAvailableWarning(err as Error); return null; } } @@ -98,23 +98,26 @@ export const createStorageSlot = ( get: () => { try { return browserStorage.getItem(key); - } catch (e) { - console.error(`Docusaurus storage error, can't get key=${key}`, e); + } catch (err) { + console.error(`Docusaurus storage error, can't get key=${key}`, err); return null; } }, set: (value) => { try { browserStorage.setItem(key, value); - } catch (e) { - console.error(`Docusaurus storage error, can't set ${key}=${value}`, e); + } catch (err) { + console.error( + `Docusaurus storage error, can't set ${key}=${value}`, + err, + ); } }, del: () => { try { browserStorage.removeItem(key); - } catch (e) { - console.error(`Docusaurus storage error, can't delete key=${key}`, e); + } catch (err) { + console.error(`Docusaurus storage error, can't delete key=${key}`, err); } }, }; diff --git a/packages/docusaurus-theme-common/src/utils/usePluralForm.ts b/packages/docusaurus-theme-common/src/utils/usePluralForm.ts index d0654e973c..15cac1f72c 100644 --- a/packages/docusaurus-theme-common/src/utils/usePluralForm.ts +++ b/packages/docusaurus-theme-common/src/utils/usePluralForm.ts @@ -75,7 +75,7 @@ function useLocalePluralForms(): LocalePluralForms { if (Intl.PluralRules) { try { return createLocalePluralForms(currentLocale); - } catch (e) { + } catch { console.error(`Failed to use Intl.PluralRules for locale "${currentLocale}". Docusaurus will fallback to a default/fallback (English) Intl.PluralRules implementation. `); diff --git a/packages/docusaurus-theme-search-algolia/src/index.ts b/packages/docusaurus-theme-search-algolia/src/index.ts index 4cb9597229..007fc9b361 100644 --- a/packages/docusaurus-theme-search-algolia/src/index.ts +++ b/packages/docusaurus-theme-search-algolia/src/index.ts @@ -85,9 +85,9 @@ export default function themeSearchAlgolia(context: LoadContext): Plugin { faviconUrl: favicon ? normalizeUrl([siteUrl, favicon]) : null, }), ); - } catch (e) { + } catch (err) { logger.error('Generating OpenSearch file failed.'); - throw e; + throw err; } } }, diff --git a/packages/docusaurus-utils/src/dataFileUtils.ts b/packages/docusaurus-utils/src/dataFileUtils.ts index c92bb4a523..0343db63c8 100644 --- a/packages/docusaurus-utils/src/dataFileUtils.ts +++ b/packages/docusaurus-utils/src/dataFileUtils.ts @@ -48,10 +48,10 @@ export async function getDataFileData( const contentString = await fs.readFile(filePath, {encoding: 'utf8'}); const unsafeContent = Yaml.load(contentString); return validate(unsafeContent); - } catch (e) { + } catch (err) { // TODO replace later by error cause, see https://v8.dev/features/error-cause logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`; - throw e; + throw err; } } diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 7dd103f9d0..fdb3f6087d 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -178,7 +178,7 @@ export function isValidPathname(str: string): boolean { // weird, but is there a better way? const parsedPathname = new URL(str, 'https://domain.com').pathname; return parsedPathname === str || parsedPathname === encodeURI(str); - } catch (e) { + } catch { return false; } } diff --git a/packages/docusaurus-utils/src/markdownParser.ts b/packages/docusaurus-utils/src/markdownParser.ts index 2217542d8a..c1a1007e51 100644 --- a/packages/docusaurus-utils/src/markdownParser.ts +++ b/packages/docusaurus-utils/src/markdownParser.ts @@ -193,9 +193,9 @@ export function parseMarkdownString( contentTitle, excerpt, }; - } catch (e) { + } catch (err) { logger.error(`Error while parsing Markdown front matter. This can happen if you use special characters in front matter values (try using double quotes around that value).`); - throw e; + throw err; } } diff --git a/packages/docusaurus/bin/beforeCli.mjs b/packages/docusaurus/bin/beforeCli.mjs index bb7976d450..283c8d576b 100644 --- a/packages/docusaurus/bin/beforeCli.mjs +++ b/packages/docusaurus/bin/beforeCli.mjs @@ -61,9 +61,9 @@ export default async function beforeCli() { notifier.config.set('lastUpdateCheck', 0); notifier.check(); } - } catch (e) { + } catch (err) { // Do not stop cli if this fails, see https://github.com/facebook/docusaurus/issues/5400 - logger.error(e); + logger.error(err); } /** diff --git a/packages/docusaurus/src/choosePort.ts b/packages/docusaurus/src/choosePort.ts index b18f875517..fbf8469093 100644 --- a/packages/docusaurus/src/choosePort.ts +++ b/packages/docusaurus/src/choosePort.ts @@ -69,7 +69,7 @@ function getProcessForPort(port: number): string | null { const directory = getDirectoryOfProcessById(processId); const command = getProcessCommand(processId); return logger.interpolate`code=${command} subdue=${`(pid ${processId})`} in path=${directory}`; - } catch (e) { + } catch { return null; } } @@ -82,47 +82,34 @@ export default async function choosePort( host: string, defaultPort: number, ): Promise { - return detect({port: defaultPort, hostname: host}).then( - (port) => - new Promise((resolve) => { - if (port === defaultPort) { - resolve(port); - return; - } - const message = - process.platform !== 'win32' && defaultPort < 1024 && !isRoot() - ? `Admin permissions are required to run a server on a port below 1024.` - : `Something is already running on port ${defaultPort}.`; - if (isInteractive) { - clearConsole(); - const existingProcess = getProcessForPort(defaultPort); - const question: prompts.PromptObject = { - type: 'confirm', - name: 'shouldChangePort', - message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${ - existingProcess ? ` Probably:\n ${existingProcess}` : '' - } + try { + const port = await detect({port: defaultPort, hostname: host}); + if (port === defaultPort) { + return port; + } + const message = + process.platform !== 'win32' && defaultPort < 1024 && !isRoot() + ? `Admin permissions are required to run a server on a port below 1024.` + : `Something is already running on port ${defaultPort}.`; + if (!isInteractive) { + logger.error(message); + return null; + } + clearConsole(); + const existingProcess = getProcessForPort(defaultPort); + const {shouldChangePort} = await prompts({ + type: 'confirm', + name: 'shouldChangePort', + message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${ + existingProcess ? ` Probably:\n ${existingProcess}` : '' + } Would you like to run the app on another port instead?`), - initial: true, - }; - prompts(question).then((answer) => { - if (answer.shouldChangePort === true) { - resolve(port); - } else { - resolve(null); - } - }); - } else { - logger.error(message); - resolve(null); - } - }), - (err) => { - throw new Error( - `Could not find an open port at ${host}. -${`Network error message: "${err.message || err}".`}`, - ); - }, - ); + initial: true, + }); + return shouldChangePort ? port : null; + } catch (err) { + logger.error`Could not find an open port at ${host}.`; + throw err; + } } diff --git a/packages/docusaurus/src/client/serverEntry.tsx b/packages/docusaurus/src/client/serverEntry.tsx index 7ff4588022..b850a73d30 100644 --- a/packages/docusaurus/src/client/serverEntry.tsx +++ b/packages/docusaurus/src/client/serverEntry.tsx @@ -47,22 +47,19 @@ export default async function render( ): Promise { try { return await doRender(locals); - } catch (e) { - logger.error`Docusaurus Node/SSR could not render static page with path path=${ - locals.path - } because of following error: -${(e as Error).stack!}`; + } catch (err) { + logger.error`Docusaurus server-side rendering could not render static page with path path=${locals.path}.`; const isNotDefinedErrorRegex = /(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i; - if (isNotDefinedErrorRegex.test((e as Error).message)) { + if (isNotDefinedErrorRegex.test((err as Error).message)) { logger.info`It looks like you are using code that should run on the client-side only. To get around it, try using code=${''} (path=${'https://docusaurus.io/docs/docusaurus-core/#browseronly'}) or code=${'ExecutionEnvironment'} (path=${'https://docusaurus.io/docs/docusaurus-core/#executionenvironment'}). It might also require to wrap your client code in code=${'useEffect'} hook and/or import a third-party library dynamically (if any).`; } - throw new Error('Server-side rendering fails due to the error above.'); + throw err; } } @@ -148,11 +145,8 @@ async function doRender(locals: Locals & {path: string}) { useShortDoctype: true, minifyJS: true, }); - } catch (e) { - logger.error`Minification of page path=${ - locals.path - } failed because of following error: -${(e as Error).stack!}`; - throw e; + } catch (err) { + logger.error`Minification of page path=${locals.path} failed.`; + throw err; } } diff --git a/packages/docusaurus/src/commands/build.ts b/packages/docusaurus/src/commands/build.ts index bb1cf4ef43..852b1eb3f9 100644 --- a/packages/docusaurus/src/commands/build.ts +++ b/packages/docusaurus/src/commands/build.ts @@ -56,9 +56,9 @@ export default async function build( forceTerminate, isLastLocale, }); - } catch (e) { + } catch (err) { logger.error`Unable to build website for locale name=${locale}.`; - throw e; + throw err; } } const context = await loadContext(siteDir, { diff --git a/packages/docusaurus/src/commands/clear.ts b/packages/docusaurus/src/commands/clear.ts index f58129bf63..b7e230a06b 100644 --- a/packages/docusaurus/src/commands/clear.ts +++ b/packages/docusaurus/src/commands/clear.ts @@ -20,11 +20,9 @@ async function removePath(entry: {path: string; description: string}) { try { await fs.remove(entry.path); logger.success`Removed the ${entry.description} at path=${entry.path}.`; - } catch (e) { - logger.error`Could not remove the ${entry.description} at path=${ - entry.path - }. -${e as string}`; + } catch (err) { + logger.error`Could not remove the ${entry.description} at path=${entry.path}.`; + logger.error(err); } } diff --git a/packages/docusaurus/src/commands/deploy.ts b/packages/docusaurus/src/commands/deploy.ts index dbfcbbcde1..fdd28ef0b2 100644 --- a/packages/docusaurus/src/commands/deploy.ts +++ b/packages/docusaurus/src/commands/deploy.ts @@ -27,9 +27,9 @@ function shellExecLog(cmd: string) { const result = shell.exec(cmd); logger.info`code=${obfuscateGitPass(cmd)} subdue=${`code: ${result.code}`}`; return result; - } catch (e) { + } catch (err) { logger.error`code=${obfuscateGitPass(cmd)}`; - throw e; + throw err; } } @@ -235,10 +235,9 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); try { await fs.copy(fromPath, toPath); - } catch (error) { - throw new Error( - `Copying build assets from "${fromPath}" to "${toPath}" failed with error "${error}".`, - ); + } catch (err) { + logger.error`Copying build assets from path=${fromPath} to path=${toPath} failed.`; + throw err; } shellExecLog('git add --all'); @@ -272,9 +271,9 @@ You can also set the deploymentBranch property in docusaurus.config.js .`); // Build site, then push to deploymentBranch branch of specified repo. try { await runDeploy(await build(siteDir, cliOptions, false)); - } catch (buildError) { - logger.error((buildError as Error).message); - process.exit(1); + } catch (err) { + logger.error('Deployment of the build output failed.'); + throw err; } } else { // Push current build to deploymentBranch branch of specified repo. diff --git a/packages/docusaurus/src/commands/writeTranslations.ts b/packages/docusaurus/src/commands/writeTranslations.ts index 017225bdf1..2959d4527f 100644 --- a/packages/docusaurus/src/commands/writeTranslations.ts +++ b/packages/docusaurus/src/commands/writeTranslations.ts @@ -36,7 +36,7 @@ async function getExtraSourceCodeFilePaths(): Promise { require.resolve('@docusaurus/theme-common/lib'), ); return globSourceCodeFilePaths([themeCommonSourceDir]); - } catch (e) { + } catch { return []; // User may not use a Docusaurus official theme? Quite unlikely... } } diff --git a/packages/docusaurus/src/server/brokenLinks.ts b/packages/docusaurus/src/server/brokenLinks.ts index 0f8a51e122..5bf04cb5c8 100644 --- a/packages/docusaurus/src/server/brokenLinks.ts +++ b/packages/docusaurus/src/server/brokenLinks.ts @@ -162,7 +162,7 @@ export function getBrokenLinksErrorMessage( async function isExistingFile(filePath: string) { try { return (await fs.stat(filePath)).isFile(); - } catch (e) { + } catch { return false; } } diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index fc2007d8f9..aa81707a77 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -131,7 +131,7 @@ const SiteUrlSchema = URISchema.required().custom((value, helpers) => { warningMessage: `the url is not supposed to contain a sub-path like '${pathname}', please use the baseUrl field for sub-paths`, }); } - } catch (e) {} + } catch {} return value; }, 'siteUrlCustomValidation'); diff --git a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts index 916b4bb5e2..6c3273e45f 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts @@ -269,7 +269,9 @@ describe('writeTranslationFileContent', () => { key1: {message: 'key1 message'}, }, }), - ).rejects.toThrowError(/Invalid translation file at/); + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"\\"bad\\" must be of type object"`, + ); }); }); diff --git a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts index a6e1134112..a80d88af1f 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translationsExtractor.test.ts @@ -57,10 +57,16 @@ const default => { `, }); + const errorMock = jest.spyOn(console, 'error').mockImplementation(); + await expect( extractSourceCodeFileTranslations(sourceCodeFilePath, TestBabelOptions), - ).rejects.toThrowError( - /Error while attempting to extract Docusaurus translations from source code file at path/, + ).rejects.toThrow(); + + expect(errorMock).toBeCalledWith( + expect.stringMatching( + /Error while attempting to extract Docusaurus translations from source code file at/, + ), ); }); diff --git a/packages/docusaurus/src/server/translations/translations.ts b/packages/docusaurus/src/server/translations/translations.ts index ba9ab885f5..d70b3c926b 100644 --- a/packages/docusaurus/src/server/translations/translations.ts +++ b/packages/docusaurus/src/server/translations/translations.ts @@ -56,10 +56,9 @@ export async function readTranslationFileContent( const content = JSON.parse(await fs.readFile(filePath, 'utf8')); ensureTranslationFileContent(content); return content; - } catch (e) { - throw new Error( - `Invalid translation file at ${filePath}.\n${(e as Error).message}`, - ); + } catch (err) { + logger.error`Invalid translation file at path=${filePath}.`; + throw err; } } return undefined; diff --git a/packages/docusaurus/src/server/translations/translationsExtractor.ts b/packages/docusaurus/src/server/translations/translationsExtractor.ts index 6b7f7403cb..069f789203 100644 --- a/packages/docusaurus/src/server/translations/translationsExtractor.ts +++ b/packages/docusaurus/src/server/translations/translationsExtractor.ts @@ -166,11 +166,9 @@ export async function extractSourceCodeFileTranslations( sourceCodeFilePath, ); return translations; - } catch (e) { - if (e instanceof Error) { - e.message = `Error while attempting to extract Docusaurus translations from source code file at path=${sourceCodeFilePath}\n${e.message}`; - } - throw e; + } catch (err) { + logger.error`Error while attempting to extract Docusaurus translations from source code file at path=${sourceCodeFilePath}.`; + throw err; } } diff --git a/packages/docusaurus/src/server/versions/index.ts b/packages/docusaurus/src/server/versions/index.ts index 32c374463a..2b95a36db4 100644 --- a/packages/docusaurus/src/server/versions/index.ts +++ b/packages/docusaurus/src/server/versions/index.ts @@ -14,19 +14,17 @@ export async function getPackageJsonVersion( ): Promise { if (await fs.pathExists(packageJsonPath)) { // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require - const {version} = require(packageJsonPath); - return typeof version === 'string' ? version : undefined; + return require(packageJsonPath).version; } return undefined; } -export async function getPackageJsonName( +async function getPackageJsonName( packageJsonPath: string, ): Promise { if (await fs.pathExists(packageJsonPath)) { // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require - const {name} = require(packageJsonPath); - return typeof name === 'string' ? name : undefined; + return require(packageJsonPath).name; } return undefined; } diff --git a/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts b/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts index 0457f6cd28..62911f77e3 100644 --- a/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts +++ b/packages/docusaurus/src/webpack/plugins/CleanWebpackPlugin.ts @@ -233,10 +233,10 @@ export default class CleanWebpackPlugin { console.warn(`clean-webpack-plugin: removed ${filename}`); }); } - } catch (error) { + } catch (err) { const needsForce = /Cannot delete files\/folders outside the current working directory\./.test( - (error as Error).message, + (err as Error).message, ); if (needsForce) { @@ -246,7 +246,7 @@ export default class CleanWebpackPlugin { throw new Error(message); } - throw error; + throw err; } } } diff --git a/packages/lqip-loader/package.json b/packages/lqip-loader/package.json index 10e7f60288..0aa247a44e 100644 --- a/packages/lqip-loader/package.json +++ b/packages/lqip-loader/package.json @@ -17,6 +17,7 @@ }, "license": "MIT", "dependencies": { + "@docusaurus/logger": "2.0.0-beta.15", "file-loader": "^6.2.0", "lodash": "^4.17.21", "node-vibrant": "^3.1.6", diff --git a/packages/lqip-loader/src/index.ts b/packages/lqip-loader/src/index.ts index 700b78895d..f60c25406f 100644 --- a/packages/lqip-loader/src/index.ts +++ b/packages/lqip-loader/src/index.ts @@ -71,8 +71,8 @@ export default async function lqipLoader( } else { callback(new Error('ERROR'), undefined); } - } catch (error) { - console.error(error); + } catch (err) { + console.error(err); callback(new Error('ERROR'), undefined); } } diff --git a/packages/lqip-loader/src/lqip.ts b/packages/lqip-loader/src/lqip.ts index e1156e778f..eb16ed33a8 100644 --- a/packages/lqip-loader/src/lqip.ts +++ b/packages/lqip-loader/src/lqip.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import logger from '@docusaurus/logger'; import Vibrant from 'node-vibrant'; import path from 'path'; import sharp from 'sharp'; @@ -22,29 +23,29 @@ const SUPPORTED_MIMES: Record = { }; export async function base64(file: string): Promise { - let extension = path.extname(file) || ''; + let extension = path.extname(file); extension = extension.split('.').pop()!; if (!SUPPORTED_MIMES[extension]) { throw new Error(ERROR_EXT); } - const data = await sharp(file).resize(10).toBuffer(); - if (data) { + try { + const data = await sharp(file).resize(10).toBuffer(); return toBase64(SUPPORTED_MIMES[extension], data); + } catch (err) { + logger.error`Generation of base64 failed for image path=${file}.`; + throw err; } - throw new Error('Unhandled promise rejection in base64 promise'); } export async function palette(file: string): Promise { const vibrant = new Vibrant(file, {}); - const pal = await vibrant.getPalette(); - if (pal) { + try { + const pal = await vibrant.getPalette(); return toPalette(pal); + } catch (err) { + logger.error`Generation of color palette failed for image path=${file}.`; + throw err; } - throw new Error(`Unhandled promise rejection in colorPalette ${pal}`); } - -process.on('unhandledRejection', (up) => { - throw up; -}); diff --git a/project-words.txt b/project-words.txt index 940a50943f..3445c1d9ea 100644 --- a/project-words.txt +++ b/project-words.txt @@ -90,6 +90,7 @@ goss goyal gtag héctor +heuristical hideable hola horiz @@ -227,13 +228,13 @@ roadmap rocketvalidator rtcts rtlcss -sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ scaleway searchbar sebastien sébastien sebastienlorber sensical +serializers setaf sida simen