refactor: unify error handling behavior (#6755)

* refactor: unify error handling behavior

* revert

* normalize paths

* test...

* change

* does this work...

* fix...

* maybe fix

* maybe fix

* fix

* fix...
This commit is contained in:
Joshua Chen 2022-02-25 15:07:13 +08:00 committed by GitHub
parent dcbf9f644e
commit f903422617
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 1123 additions and 299 deletions

View file

@ -92,9 +92,9 @@ async function generateTemplateExample(template) {
); );
console.log(`Generated example for template ${template}`); console.log(`Generated example for template ${template}`);
} catch (error) { } catch (err) {
console.error(`Failed to generated example for template ${template}`); console.error(`Failed to generated example for template ${template}`);
throw error; throw err;
} }
} }
@ -115,12 +115,12 @@ function updateStarters() {
console.log(`forcePushGitSubtree command: ${command}`); console.log(`forcePushGitSubtree command: ${command}`);
shell.exec(command); shell.exec(command);
console.log('forcePushGitSubtree success!'); console.log('forcePushGitSubtree success!');
} catch (e) { } catch (err) {
console.error( console.error(
`Can't force push to git subtree with command '${command}'`, `Can't force push to git subtree with command '${command}'`,
); );
console.error(`If it's a permission problem, ask @slorber`); console.error(`If it's a permission problem, ask @slorber`);
console.error(e); console.error(err);
} }
console.log(''); console.log('');
} }

View file

@ -53,4 +53,5 @@ export default {
location: {href: 'https://docusaurus.io'}, location: {href: 'https://docusaurus.io'},
}, },
}, },
snapshotSerializers: ['<rootDir>/jest/snapshotPathNormalizer.js'],
}; };

174
jest/snapshotPathNormalizer.js vendored Normal file
View file

@ -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 <PROJECT_ROOT>
(val) => val.split(cwdReal).join('<PROJECT_ROOT>'),
(val) => val.split(cwd).join('<PROJECT_ROOT>'),
// Replace home directory with <TEMP_DIR>
(val) => val.split(tempDirReal).join('<TEMP_DIR>'),
(val) => val.split(tempDir).join('<TEMP_DIR>'),
// Replace home directory with <HOME_DIR>
(val) => val.split(homeDirReal).join('<HOME_DIR>'),
(val) => val.split(homeDir).join('<HOME_DIR>'),
// handle HOME_DIR nested inside TEMP_DIR
(val) =>
val
.split(`<TEMP_DIR>${path.sep + homeRelativeToTemp}`)
.join('<HOME_DIR>'),
(val) =>
val
.split(`<TEMP_DIR>${path.sep + homeRelativeToTempReal}`)
.join('<HOME_DIR>'), // untested
(val) =>
val
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTempReal}`)
.join('<HOME_DIR>'),
(val) =>
val
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTemp}`)
.join('<HOME_DIR>'), // untested
// In case the CWD is escaped
(val) => val.split(escapePath(cwd)).join('<PROJECT_ROOT>'),
// 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;
}
}

View file

@ -58,10 +58,9 @@ type Options = RemarkAndRehypePluginOptions & {
async function readMetadataPath(metadataPath: string) { async function readMetadataPath(metadataPath: string) {
try { try {
return await fs.readFile(metadataPath, 'utf8'); return await fs.readFile(metadataPath, 'utf8');
} catch (e) { } catch (err) {
throw new Error( logger.error`MDX loader can't read MDX metadata file path=${metadataPath}. Maybe the isMDXPartial option function was not provided?`;
`MDX loader can't read MDX metadata file for path ${metadataPath}. Maybe the isMDXPartial option function was not provided?`, throw err;
);
} }
} }

View file

@ -7,3 +7,5 @@
## `<div> Test </div>` ## `<div> Test </div>`
## `<div><i>Test</i></div>` ## `<div><i>Test</i></div>`
## [`<div><i>Test</i></div>`](/some/link)

View file

@ -26,6 +26,11 @@ exports[`inline code should be escaped 1`] = `
value: '<code>&lt;div&gt;&lt;i&gt;Test&lt;/i&gt;&lt;/div&gt;</code>', value: '<code>&lt;div&gt;&lt;i&gt;Test&lt;/i&gt;&lt;/div&gt;</code>',
id: 'divitestidiv', id: 'divitestidiv',
level: 2 level: 2
},
{
value: '<code>&lt;div&gt;&lt;i&gt;Test&lt;/i&gt;&lt;/div&gt;</code>',
id: 'divitestidiv-1',
level: 2
} }
]; ];
@ -38,6 +43,8 @@ exports[`inline code should be escaped 1`] = `
## \`<div> Test </div>\` ## \`<div> Test </div>\`
## \`<div><i>Test</i></div>\` ## \`<div><i>Test</i></div>\`
## [\`<div><i>Test</i></div>\`](/some/link)
" "
`; `;

View file

@ -0,0 +1 @@
![invalid image](/invalid.png)

View file

@ -1,5 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`transformImage plugin does not choke on invalid image 1`] = `
"<img loading=\\"lazy\\" alt={\\"invalid image\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/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 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."`; 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 <img /> 1`] = ` exports[`transformImage plugin transform md images to <img /> 1`] = `
"![img](https://example.com/img.png) "![img](https://example.com/img.png)
<img loading=\\"lazy\\" src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img from second static folder\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" /> <img loading=\\"lazy\\" alt={\\"img from second static folder\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" />
<img loading=\\"lazy\\" alt={\\"img from second static folder\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" /> <img loading=\\"lazy\\" alt={\\"img from second static folder\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static2/img2.png\\").default} width=\\"256\\" height=\\"82\\" />
<img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"Title\\" width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"Title\\" width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with &quot;quotes&quot;\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"&#39;Quoted&#39; title\\" width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with &quot;quotes&quot;\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} title=\\"&#39;Quoted&#39; title\\" width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"site alias\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"site alias\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with hash\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#light'} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with hash\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#light'} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with hash\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#dark'} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with hash\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png\\").default + '#dark'} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with query\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with query\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with query\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with query\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default} width=\\"200\\" height=\\"200\\" />
<img loading=\\"lazy\\" alt={\\"img with both\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default + '#light'} width=\\"200\\" height=\\"200\\" /> <img loading=\\"lazy\\" alt={\\"img with both\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/img.png?w=10&h=10\\").default + '#light'} width=\\"200\\" height=\\"200\\" />
## Heading ## Heading

View file

@ -21,10 +21,7 @@ const processFixture = async (name, options) => {
.use(plugin, {...options, filePath}) .use(plugin, {...options, filePath})
.process(file); .process(file);
return result return result.toString();
.toString()
.replace(/\\\\/g, '/')
.replace(new RegExp(process.cwd().replace(/\\/g, '/'), 'g'), '[CWD]');
}; };
const staticDirs = [ const staticDirs = [
@ -60,4 +57,11 @@ describe('transformImage plugin', () => {
const result = await processFixture('pathname', {staticDirs}); const result = await processFixture('pathname', {staticDirs});
expect(result).toMatchSnapshot(); 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);
});
}); });

View file

@ -66,9 +66,9 @@ async function toImageRequireNode(
if (size.height) { if (size.height) {
height = ` height="${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. 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( Object.keys(jsxNode).forEach(

View file

@ -12,13 +12,13 @@ exports[`transformAsset plugin pathname protocol 1`] = `
exports[`transformAsset plugin transform md links to <a /> 1`] = ` exports[`transformAsset plugin transform md links to <a /> 1`] = `
"[asset](https://example.com/asset.pdf) "[asset](https://example.com/asset.pdf)
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}></a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default + '#page=2'}>asset with hash</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default + '#page=2'}>asset with hash</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default} title=\\"Title\\">asset</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default} title=\\"Title\\">asset</a>
[page](noUrl.md) [page](noUrl.md)
@ -32,24 +32,24 @@ exports[`transformAsset plugin transform md links to <a /> 1`] = `
[assets](/github/!file-loader!/assets.pdf) [assets](/github/!file-loader!/assets.pdf)
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}>asset</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static2/asset2.pdf').default}>asset2</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static2/asset2.pdf').default}>asset2</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>staticAsset.pdf</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>staticAsset.pdf</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>@site/static/staticAsset.pdf</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>@site/static/staticAsset.pdf</a>
<a target=\\"_blank\\" href={require('![CWD]/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</a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/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</a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>Just staticAsset.pdf</a>, and <a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}><strong>awesome</strong> staticAsset 2.pdf &#39;It is really &quot;AWESOME&quot;&#39;</a>, but also <a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>coded <code>staticAsset 3.pdf</code></a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>Just staticAsset.pdf</a>, and <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}><strong>awesome</strong> staticAsset 2.pdf &#39;It is really &quot;AWESOME&quot;&#39;</a>, but also <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAsset.pdf').default}>coded <code>staticAsset 3.pdf</code></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAssetImage.png').default}><img loading=\\"lazy\\" alt={\\"Clickable Docusaurus logo\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/staticAssetImage.png\\").default} width=\\"200\\" height=\\"200\\" /></a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticAssetImage.png').default}><img loading=\\"lazy\\" alt={\\"Clickable Docusaurus logo\\"} src={require(\\"!<PROJECT_ROOT>/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[contenthash].[ext]&fallback=<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js!./static/staticAssetImage.png\\").default} width=\\"200\\" height=\\"200\\" /></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}><span style={{color: \\"red\\"}}>Stylized link to asset file</span></a> <a target=\\"_blank\\" href={require('!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./asset.pdf').default}><span style={{color: \\"red\\"}}>Stylized link to asset file</span></a>
<a target=\\"_blank\\" href={require('./data.raw!=![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./data.json').default}>json</a> <a target=\\"_blank\\" href={require('./data.raw!=!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./data.json').default}>json</a>
<a target=\\"_blank\\" href={require('./static/staticjson.raw!=![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticjson.json').default}>static json</a> <a target=\\"_blank\\" href={require('./static/staticjson.raw!=!<PROJECT_ROOT>/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[contenthash].[ext]!./static/staticjson.json').default}>static json</a>
" "
`; `;

View file

@ -30,10 +30,7 @@ const processFixture = async (name: string, options?) => {
}) })
.process(file); .process(file);
return result return result.toString();
.toString()
.replace(/\\\\/g, '/')
.replace(new RegExp(process.cwd().replace(/\\/g, '/'), 'g'), '[CWD]');
}; };
describe('transformAsset plugin', () => { describe('transformAsset plugin', () => {

View file

@ -11,7 +11,7 @@ import type {Parent} from 'unist';
import type {PhrasingContent, Heading} from 'mdast'; import type {PhrasingContent, Heading} from 'mdast';
export function stringifyContent(node: Parent): string { 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 { export function toValue(node: PhrasingContent | Heading): string {

View file

@ -0,0 +1,592 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`migration test complex website: copy 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/static",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/blog",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/blog",
],
]
`;
exports[`migration test complex website: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages/",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 <Layout />;
};
",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/static",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/blog",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/blog",
],
]
`;
exports[`migration test missing versions: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages/",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 <Layout />;
};
",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/static",
],
]
`;
exports[`migration test simple website: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages/",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 <Layout />;
};
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-commands.md",
"---
id: commands
title: CLI Commands
---
## Doc ",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-doc-markdown.md",
"---
id: doc-markdown
title: Markdown Features
---
## Doc",
],
Array [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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 [
"<PROJECT_ROOT>/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\\"
}
}",
],
]
`;

View file

@ -9,53 +9,38 @@ import {migrateDocusaurusProject} from '../index';
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; 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', () => { describe('migration test', () => {
const fixtureDir = path.join(__dirname, '__fixtures__');
test('simple website', async () => { test('simple website', async () => {
const siteDir = path.join( const siteDir = path.join(fixtureDir, 'simple_website', 'website');
__dirname, const newDir = path.join(fixtureDir, 'migrated_simple_site');
'__fixtures__', await testMigration(siteDir, newDir);
'simple_website',
'website',
);
const newDir = path.join(__dirname, '__fixtures__', 'migrated_simple_site');
await expect(
migrateDocusaurusProject(siteDir, newDir),
).resolves.toBeUndefined();
await fs.remove(newDir);
}); });
test('complex website', async () => { test('complex website', async () => {
const siteDir = path.join( const siteDir = path.join(fixtureDir, 'complex_website', 'website');
__dirname, const newDir = path.join(fixtureDir, 'migrated_complex_site');
'__fixtures__', await testMigration(siteDir, newDir);
'complex_website',
'website',
);
const newDir = path.join(
__dirname,
'__fixtures__',
'migrated_complex_site',
);
await expect(
migrateDocusaurusProject(siteDir, newDir),
).resolves.toBeUndefined();
await fs.remove(newDir);
}); });
test('missing versions', async () => { test('missing versions', async () => {
const siteDir = path.join( const siteDir = path.join(fixtureDir, 'missing_version_website', 'website');
__dirname, const newDir = path.join(fixtureDir, 'migrated_missing_version_site');
'__fixtures__', await testMigration(siteDir, newDir);
'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);
}); });
}); });

View file

@ -69,6 +69,7 @@ export function shouldQuotifyFrontMatter([key, value]: [
// TODO this is not ideal to have to maintain such a list of allowed chars // TODO this is not ideal to have to maintain such a list of allowed chars
// maybe we should quotify if gray-matter throws instead? // maybe we should quotify if gray-matter throws instead?
return !String(value).match( return !String(value).match(
// cSpell:ignore sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ
/^[\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$]+$/, /^[\w .\-sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ!;,=+_?'`&#()[\]§%€$]+$/,
); );
} }

View file

@ -45,18 +45,22 @@ function sanitizedFileContent(
migrateMDFiles: boolean, migrateMDFiles: boolean,
): string { ): string {
const extractedData = extractMetadata(content); const extractedData = extractMetadata(content);
const extractedMetaData = Object.entries(extractedData.metadata).reduce( const extractedMetaData = Object.entries(extractedData.metadata)
(metaData, [key, value]) => .map(
`${metaData}\n${key}: ${ ([key, value]) =>
shouldQuotifyFrontMatter([key, value]) ? `"${value}"` : value `${key}: ${
}`, shouldQuotifyFrontMatter([key, value]) ? `"${value}"` : value
'', }`,
); )
const sanitizedData = `---${extractedMetaData}\n---\n${ .join('\n');
migrateMDFiles const sanitizedData = `---
? sanitizeMD(extractedData.rawContent) ${extractedMetaData}
: extractedData.rawContent ---
}`; ${
migrateMDFiles
? sanitizeMD(extractedData.rawContent)
: extractedData.rawContent
}`;
return sanitizedData; return sanitizedData;
} }
@ -106,8 +110,8 @@ export async function migrateDocusaurusProject(
try { try {
createClientRedirects(migrationContext); createClientRedirects(migrationContext);
logger.success('Created client redirect for non clean URL'); logger.success('Created client redirect for non clean URL');
} catch (e) { } catch (err) {
logger.error(`Failed to creating redirects: ${e}`); logger.error(`Failed to creating redirects: ${err}`);
errorCount += 1; errorCount += 1;
} }
if (shouldMigratePages) { if (shouldMigratePages) {
@ -116,8 +120,8 @@ export async function migrateDocusaurusProject(
logger.success( logger.success(
'Created new doc pages (check migration page for more details)', 'Created new doc pages (check migration page for more details)',
); );
} catch (e) { } catch (err) {
logger.error(`Failed to create new doc pages: ${e}`); logger.error(`Failed to create new doc pages: ${err}`);
errorCount += 1; errorCount += 1;
} }
} else { } else {
@ -126,8 +130,8 @@ export async function migrateDocusaurusProject(
logger.success( logger.success(
'Created landing page (check migration page for more details)', 'Created landing page (check migration page for more details)',
); );
} catch (e) { } catch (err) {
logger.error(`Failed to create landing page: ${e}`); logger.error(`Failed to create landing page: ${err}`);
errorCount += 1; errorCount += 1;
} }
} }
@ -135,34 +139,34 @@ export async function migrateDocusaurusProject(
try { try {
await migrateStaticFiles(migrationContext); await migrateStaticFiles(migrationContext);
logger.success('Migrated static folder'); logger.success('Migrated static folder');
} catch (e) { } catch (err) {
logger.error(`Failed to copy static folder: ${e}`); logger.error(`Failed to copy static folder: ${err}`);
errorCount += 1; errorCount += 1;
} }
try { try {
await migrateBlogFiles(migrationContext); await migrateBlogFiles(migrationContext);
} catch (e) { } catch (err) {
logger.error(`Failed to migrate blogs: ${e}`); logger.error(`Failed to migrate blogs: ${err}`);
errorCount += 1; errorCount += 1;
} }
try { try {
await handleVersioning(migrationContext); await handleVersioning(migrationContext);
} catch (e) { } catch (err) {
logger.error(`Failed to migrate versioned docs: ${e}`); logger.error(`Failed to migrate versioned docs: ${err}`);
errorCount += 1; errorCount += 1;
} }
try { try {
await migrateLatestDocs(migrationContext); await migrateLatestDocs(migrationContext);
} catch (e) { } catch (err) {
logger.error(`Failed to migrate docs: ${e}`); logger.error(`Failed to migrate docs: ${err}`);
errorCount += 1; errorCount += 1;
} }
try { try {
await migrateLatestSidebar(migrationContext); await migrateLatestSidebar(migrationContext);
} catch (e) { } catch (err) {
logger.error(`Failed to migrate sidebar: ${e}`); logger.error(`Failed to migrate sidebar: ${err}`);
errorCount += 1; errorCount += 1;
} }
@ -174,15 +178,15 @@ export async function migrateDocusaurusProject(
logger.success( logger.success(
`Created a new config file with new navbar and footer config`, `Created a new config file with new navbar and footer config`,
); );
} catch (e) { } catch (err) {
logger.error(`Failed to create config file: ${e}`); logger.error(`Failed to create config file: ${err}`);
errorCount += 1; errorCount += 1;
} }
try { try {
await migratePackageFile(migrationContext); await migratePackageFile(migrationContext);
} catch (e) { } catch (err) {
logger.error( logger.error(
`Error occurred while creating package.json file for project: ${e}`, `Error occurred while creating package.json file for project: ${err}`,
); );
errorCount += 1; errorCount += 1;
} }
@ -387,8 +391,8 @@ async function createPages(context: MigrationContext) {
await fs.writeFile(filePath, migratePage(content)); await fs.writeFile(filePath, migratePage(content));
}), }),
); );
} catch (e) { } catch (err) {
logger.error(`Unable to migrate Pages: ${e}`); logger.error(`Unable to migrate Pages: ${err}`);
await createDefaultLandingPage(context); await createDefaultLandingPage(context);
} }
} else { } else {
@ -664,9 +668,7 @@ async function migrateLatestSidebar(context: MigrationContext) {
await fs.writeFile(path.join(newDir, 'src', 'css', 'customTheme.css'), css); await fs.writeFile(path.join(newDir, 'src', 'css', 'customTheme.css'), css);
context.v2Config.presets[0][1].theme.customCss = path.join( context.v2Config.presets[0][1].theme.customCss = path.join(
path.relative(newDir, path.join(siteDir, '..')), path.relative(newDir, path.join(siteDir, '..')),
'src', 'src/css/customTheme.css',
'css',
'customTheme.css',
); );
} }
} }

View file

@ -64,8 +64,8 @@ function validateCollectedRedirects(
try { try {
validateRedirect(redirect); validateRedirect(redirect);
return undefined; return undefined;
} catch (e) { } catch (err) {
return (e as Error).message; return (err as Error).message;
} }
}) })
.filter(Boolean); .filter(Boolean);

View file

@ -26,8 +26,7 @@ Array [
<link href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post\\"/> <link href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post\\"/>
<updated>2021-03-05T00:00:00.000Z</updated> <updated>2021-03-05T00:00:00.000Z</updated>
<summary type=\\"html\\"><![CDATA[HTML Heading 1]]></summary> <summary type=\\"html\\"><![CDATA[HTML Heading 1]]></summary>
<content type=\\"html\\"><![CDATA[<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-2\\">Heading 2<a class=\\"hash-link\\" href=\\"#heading-2\\" title=\\"Direct link to heading\\"></a></h2><h3 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-3\\">Heading 3<a class=\\"hash-link\\" href=\\"#heading-3\\" title=\\"Direct link to heading\\"></a></h3><h4 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-4\\">Heading 4<a class=\\"hash-link\\" href=\\"#heading-4\\" title=\\"Direct link to heading\\"></a></h4><h5 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-5\\">Heading 5<a class=\\"hash-link\\" href=\\"#heading-5\\" title=\\"Direct link to heading\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a> <content type=\\"html\\"><![CDATA[<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-2\\">Heading 2<a class=\\"hash-link\\" href=\\"#heading-2\\" title=\\"Direct link to heading\\"></a></h2><h3 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-3\\">Heading 3<a class=\\"hash-link\\" href=\\"#heading-3\\" title=\\"Direct link to heading\\"></a></h3><h4 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-4\\">Heading 4<a class=\\"hash-link\\" href=\\"#heading-4\\" title=\\"Direct link to heading\\"></a></h4><h5 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-5\\">Heading 5<a class=\\"hash-link\\" href=\\"#heading-5\\" title=\\"Direct link to heading\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a><img src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\"></p>]]></content>
<img src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\"></p>]]></content>
</entry> </entry>
<entry> <entry>
<title type=\\"html\\"><![CDATA[Complex Slug]]></title> <title type=\\"html\\"><![CDATA[Complex Slug]]></title>
@ -103,7 +102,7 @@ Array [
}, },
{ {
\\"id\\": \\"/mdx-blog-post\\", \\"id\\": \\"/mdx-blog-post\\",
\\"content_html\\": \\"<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-2\\\\\\">Heading 2<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-2\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h2><h3 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-3\\\\\\">Heading 3<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-3\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h3><h4 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-4\\\\\\">Heading 4<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-4\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h4><h5 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-5\\\\\\">Heading 5<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-5\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\\\\\"https://v2.docusaurus.io/\\\\\\" target=\\\\\\"_blank\\\\\\" rel=\\\\\\"noopener noreferrer\\\\\\">link</a>\\\\n<img src=\\\\\\"https://v2.docusaurus.io/\\\\\\" alt=\\\\\\"image\\\\\\"></p>\\", \\"content_html\\": \\"<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-2\\\\\\">Heading 2<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-2\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h2><h3 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-3\\\\\\">Heading 3<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-3\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h3><h4 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-4\\\\\\">Heading 4<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-4\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h4><h5 class=\\\\\\"anchor anchorWithStickyNavbar_mojV\\\\\\" id=\\\\\\"heading-5\\\\\\">Heading 5<a class=\\\\\\"hash-link\\\\\\" href=\\\\\\"#heading-5\\\\\\" title=\\\\\\"Direct link to heading\\\\\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\\\\\"https://v2.docusaurus.io/\\\\\\" target=\\\\\\"_blank\\\\\\" rel=\\\\\\"noopener noreferrer\\\\\\">link</a><img src=\\\\\\"https://v2.docusaurus.io/\\\\\\" alt=\\\\\\"image\\\\\\"></p>\\",
\\"url\\": \\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post\\", \\"url\\": \\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post\\",
\\"title\\": \\"Full Blog Sample\\", \\"title\\": \\"Full Blog Sample\\",
\\"summary\\": \\"HTML Heading 1\\", \\"summary\\": \\"HTML Heading 1\\",
@ -197,8 +196,7 @@ Array [
<guid>/mdx-blog-post</guid> <guid>/mdx-blog-post</guid>
<pubDate>Fri, 05 Mar 2021 00:00:00 GMT</pubDate> <pubDate>Fri, 05 Mar 2021 00:00:00 GMT</pubDate>
<description><![CDATA[HTML Heading 1]]></description> <description><![CDATA[HTML Heading 1]]></description>
<content:encoded><![CDATA[<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-2\\">Heading 2<a class=\\"hash-link\\" href=\\"#heading-2\\" title=\\"Direct link to heading\\"></a></h2><h3 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-3\\">Heading 3<a class=\\"hash-link\\" href=\\"#heading-3\\" title=\\"Direct link to heading\\"></a></h3><h4 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-4\\">Heading 4<a class=\\"hash-link\\" href=\\"#heading-4\\" title=\\"Direct link to heading\\"></a></h4><h5 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-5\\">Heading 5<a class=\\"hash-link\\" href=\\"#heading-5\\" title=\\"Direct link to heading\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a> <content:encoded><![CDATA[<h1>HTML Heading 1</h1><h2>HTML Heading 2</h2><p>HTML Paragraph</p><p>Import DOM</p><h1>Heading 1</h1><h2 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-2\\">Heading 2<a class=\\"hash-link\\" href=\\"#heading-2\\" title=\\"Direct link to heading\\"></a></h2><h3 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-3\\">Heading 3<a class=\\"hash-link\\" href=\\"#heading-3\\" title=\\"Direct link to heading\\"></a></h3><h4 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-4\\">Heading 4<a class=\\"hash-link\\" href=\\"#heading-4\\" title=\\"Direct link to heading\\"></a></h4><h5 class=\\"anchor anchorWithStickyNavbar_mojV\\" id=\\"heading-5\\">Heading 5<a class=\\"hash-link\\" href=\\"#heading-5\\" title=\\"Direct link to heading\\"></a></h5><ul><li>list1</li><li>list2</li><li>list3</li></ul><ul><li>list1</li><li>list2</li><li>list3</li></ul><p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p><p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a><img src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\"></p>]]></content:encoded>
<img src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\"></p>]]></content:encoded>
</item> </item>
<item> <item>
<title><![CDATA[Complex Slug]]></title> <title><![CDATA[Complex Slug]]></title>

View file

@ -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",
},
}
`;

View file

@ -54,9 +54,9 @@ function testField(params: {
)}`, )}`,
), ),
); );
} catch (e) { } catch (err) {
// eslint-disable-next-line jest/no-conditional-expect // eslint-disable-next-line jest/no-conditional-expect
expect(e.message).toMatch(new RegExp(escapeStringRegexp(message))); expect(err.message).toMatch(new RegExp(escapeStringRegexp(message)));
} }
}); });
}); });

View file

@ -479,4 +479,17 @@ describe('loadBlog', () => {
expect(Object.keys(blogTags).length).toEqual(2); expect(Object.keys(blogTags).length).toEqual(2);
expect(blogTags).toMatchSnapshot(); 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();
});
}); });

View file

@ -157,8 +157,9 @@ function formatBlogPostDate(locale: string, date: Date): string {
year: 'numeric', year: 'numeric',
timeZone: 'UTC', timeZone: 'UTC',
}).format(date); }).format(date);
} catch (e) { } catch (err) {
throw new Error(`Can't format blog post date "${date}"`); logger.error`Can't format blog post date "${String(date)}"`;
throw err;
} }
} }
@ -172,12 +173,9 @@ async function parseBlogPostMarkdownFile(blogSourceAbsolute: string) {
...result, ...result,
frontMatter: validateBlogPostFrontMatter(result.frontMatter), frontMatter: validateBlogPostFrontMatter(result.frontMatter),
}; };
} catch (e) { } catch (err) {
throw new Error( logger.error`Error while parsing blog post file path=${blogSourceAbsolute}.`;
`Error while parsing blog post file ${blogSourceAbsolute}: "${ throw err;
(e as Error).message
}".`,
);
} }
} }
@ -246,8 +244,8 @@ async function processBlogSourceFile(
includeAuthor: false, includeAuthor: false,
}); });
return result.date; return result.date;
} catch (e) { } catch (err) {
logger.error(e); logger.error(err);
return (await fs.stat(blogSourceAbsolute)).birthtime; return (await fs.stat(blogSourceAbsolute)).birthtime;
} }
} }
@ -357,9 +355,9 @@ export async function generateBlogPosts(
options, options,
authorsMap, authorsMap,
); );
} catch (e) { } catch (err) {
logger.error`Processing of blog source file failed for path path=${blogSourceFile}.`; logger.error`Processing of blog source file path=${blogSourceFile} failed.`;
throw e; throw err;
} }
}), }),
) )

View file

@ -73,8 +73,8 @@ describe('docsVersion', () => {
DEFAULT_PLUGIN_ID, DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowError(
`"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`, '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.',
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -83,8 +83,8 @@ describe('docsVersion', () => {
DEFAULT_PLUGIN_ID, DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowError(
`"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`, '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.',
); );
}); });

View file

@ -51,9 +51,9 @@ function testField(params: {
)}`, )}`,
), ),
); );
} catch (e) { } catch (err) {
// eslint-disable-next-line jest/no-conditional-expect // eslint-disable-next-line jest/no-conditional-expect
expect(e.message).toMatch(new RegExp(escapeStringRegexp(message))); expect(err.message).toMatch(new RegExp(escapeStringRegexp(message)));
} }
}); });
}); });

View file

@ -123,15 +123,13 @@ function createTestUtils({
async function generateNavigation( async function generateNavigation(
docFiles: DocFile[], docFiles: DocFile[],
): Promise<[DocNavLink | undefined, DocNavLink | undefined][]> { ): Promise<[DocNavLink | undefined, DocNavLink | undefined][]> {
const rawDocs = await Promise.all( const rawDocs = docFiles.map((docFile) =>
docFiles.map((docFile) => processDocMetadata({
processDocMetadata({ docFile,
docFile, versionMetadata,
versionMetadata, context,
context, options,
options, }),
}),
),
); );
const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, { const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
sidebarItemsGenerator: ({defaultSidebarItemsGenerator, ...args}) => sidebarItemsGenerator: ({defaultSidebarItemsGenerator, ...args}) =>

View file

@ -275,9 +275,9 @@ export function processDocMetadata(args: {
}): DocMetadataBase { }): DocMetadataBase {
try { try {
return doProcessDocMetadata(args); 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}`; 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;
} }
} }

View file

@ -196,9 +196,9 @@ export default async function pluginContentDocs(
async function loadVersion(versionMetadata: VersionMetadata) { async function loadVersion(versionMetadata: VersionMetadata) {
try { try {
return await doLoadVersion(versionMetadata); return await doLoadVersion(versionMetadata);
} catch (e) { } catch (err) {
logger.error`Loading of version failed for version name=${versionMetadata.versionName}`; logger.error`Loading of version failed for version name=${versionMetadata.versionName}`;
throw e; throw err;
} }
} }

View file

@ -27,12 +27,12 @@ export async function getFileLastUpdate(
includeAuthor: true, includeAuthor: true,
}); });
return {timestamp: result.timestamp, author: result.author}; return {timestamp: result.timestamp, author: result.author};
} catch (e) { } catch (err) {
if (e instanceof GitNotFoundError && !showedGitRequirementError) { if (err instanceof GitNotFoundError && !showedGitRequirementError) {
logger.warn('Sorry, the docs plugin last update options require Git.'); logger.warn('Sorry, the docs plugin last update options require Git.');
showedGitRequirementError = true; showedGitRequirementError = true;
} else { } else {
logger.error(e); logger.error(err);
} }
return null; return null;
} }

View file

@ -178,8 +178,8 @@ export async function createVersionRoutes({
try { try {
return await doCreateVersionRoutes(loadedVersion); return await doCreateVersionRoutes(loadedVersion);
} catch (e) { } catch (err) {
logger.error`Can't create version routes for version name=${loadedVersion.versionName}`; logger.error`Can't create version routes for version name=${loadedVersion.versionName}`;
throw e; throw err;
} }
} }

View file

@ -61,9 +61,9 @@ async function readCategoriesMetadata(contentPath: string) {
); );
try { try {
return validateCategoryMetadataFile(Yaml.load(content)); return validateCategoryMetadataFile(Yaml.load(content));
} catch (e) { } catch (err) {
logger.error`The docs sidebar category metadata file path=${filePath} looks invalid!`; logger.error`The docs sidebar category metadata file path=${filePath} looks invalid!`;
throw e; throw err;
} }
}), }),
); );

View file

@ -26,8 +26,8 @@ function getBrowserStorage(
} }
try { try {
return window[storageType]; return window[storageType];
} catch (e) { } catch (err) {
logOnceBrowserStorageNotAvailableWarning(e as Error); logOnceBrowserStorageNotAvailableWarning(err as Error);
return null; return null;
} }
} }
@ -98,23 +98,26 @@ export const createStorageSlot = (
get: () => { get: () => {
try { try {
return browserStorage.getItem(key); return browserStorage.getItem(key);
} catch (e) { } catch (err) {
console.error(`Docusaurus storage error, can't get key=${key}`, e); console.error(`Docusaurus storage error, can't get key=${key}`, err);
return null; return null;
} }
}, },
set: (value) => { set: (value) => {
try { try {
browserStorage.setItem(key, value); browserStorage.setItem(key, value);
} catch (e) { } catch (err) {
console.error(`Docusaurus storage error, can't set ${key}=${value}`, e); console.error(
`Docusaurus storage error, can't set ${key}=${value}`,
err,
);
} }
}, },
del: () => { del: () => {
try { try {
browserStorage.removeItem(key); browserStorage.removeItem(key);
} catch (e) { } catch (err) {
console.error(`Docusaurus storage error, can't delete key=${key}`, e); console.error(`Docusaurus storage error, can't delete key=${key}`, err);
} }
}, },
}; };

View file

@ -75,7 +75,7 @@ function useLocalePluralForms(): LocalePluralForms {
if (Intl.PluralRules) { if (Intl.PluralRules) {
try { try {
return createLocalePluralForms(currentLocale); return createLocalePluralForms(currentLocale);
} catch (e) { } catch {
console.error(`Failed to use Intl.PluralRules for locale "${currentLocale}". console.error(`Failed to use Intl.PluralRules for locale "${currentLocale}".
Docusaurus will fallback to a default/fallback (English) Intl.PluralRules implementation. Docusaurus will fallback to a default/fallback (English) Intl.PluralRules implementation.
`); `);

View file

@ -85,9 +85,9 @@ export default function themeSearchAlgolia(context: LoadContext): Plugin<void> {
faviconUrl: favicon ? normalizeUrl([siteUrl, favicon]) : null, faviconUrl: favicon ? normalizeUrl([siteUrl, favicon]) : null,
}), }),
); );
} catch (e) { } catch (err) {
logger.error('Generating OpenSearch file failed.'); logger.error('Generating OpenSearch file failed.');
throw e; throw err;
} }
} }
}, },

View file

@ -48,10 +48,10 @@ export async function getDataFileData<T>(
const contentString = await fs.readFile(filePath, {encoding: 'utf8'}); const contentString = await fs.readFile(filePath, {encoding: 'utf8'});
const unsafeContent = Yaml.load(contentString); const unsafeContent = Yaml.load(contentString);
return validate(unsafeContent); return validate(unsafeContent);
} catch (e) { } catch (err) {
// TODO replace later by error cause, see https://v8.dev/features/error-cause // TODO replace later by error cause, see https://v8.dev/features/error-cause
logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`; logger.error`The ${params.fileType} file at path=${filePath} looks invalid.`;
throw e; throw err;
} }
} }

View file

@ -178,7 +178,7 @@ export function isValidPathname(str: string): boolean {
// weird, but is there a better way? // weird, but is there a better way?
const parsedPathname = new URL(str, 'https://domain.com').pathname; const parsedPathname = new URL(str, 'https://domain.com').pathname;
return parsedPathname === str || parsedPathname === encodeURI(str); return parsedPathname === str || parsedPathname === encodeURI(str);
} catch (e) { } catch {
return false; return false;
} }
} }

View file

@ -193,9 +193,9 @@ export function parseMarkdownString(
contentTitle, contentTitle,
excerpt, excerpt,
}; };
} catch (e) { } catch (err) {
logger.error(`Error while parsing Markdown front matter. 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).`); This can happen if you use special characters in front matter values (try using double quotes around that value).`);
throw e; throw err;
} }
} }

View file

@ -61,9 +61,9 @@ export default async function beforeCli() {
notifier.config.set('lastUpdateCheck', 0); notifier.config.set('lastUpdateCheck', 0);
notifier.check(); notifier.check();
} }
} catch (e) { } catch (err) {
// Do not stop cli if this fails, see https://github.com/facebook/docusaurus/issues/5400 // Do not stop cli if this fails, see https://github.com/facebook/docusaurus/issues/5400
logger.error(e); logger.error(err);
} }
/** /**

View file

@ -69,7 +69,7 @@ function getProcessForPort(port: number): string | null {
const directory = getDirectoryOfProcessById(processId); const directory = getDirectoryOfProcessById(processId);
const command = getProcessCommand(processId); const command = getProcessCommand(processId);
return logger.interpolate`code=${command} subdue=${`(pid ${processId})`} in path=${directory}`; return logger.interpolate`code=${command} subdue=${`(pid ${processId})`} in path=${directory}`;
} catch (e) { } catch {
return null; return null;
} }
} }
@ -82,47 +82,34 @@ export default async function choosePort(
host: string, host: string,
defaultPort: number, defaultPort: number,
): Promise<number | null> { ): Promise<number | null> {
return detect({port: defaultPort, hostname: host}).then( try {
(port) => const port = await detect({port: defaultPort, hostname: host});
new Promise((resolve) => { if (port === defaultPort) {
if (port === defaultPort) { return port;
resolve(port); }
return; const message =
} process.platform !== 'win32' && defaultPort < 1024 && !isRoot()
const message = ? `Admin permissions are required to run a server on a port below 1024.`
process.platform !== 'win32' && defaultPort < 1024 && !isRoot() : `Something is already running on port ${defaultPort}.`;
? `Admin permissions are required to run a server on a port below 1024.` if (!isInteractive) {
: `Something is already running on port ${defaultPort}.`; logger.error(message);
if (isInteractive) { return null;
clearConsole(); }
const existingProcess = getProcessForPort(defaultPort); clearConsole();
const question: prompts.PromptObject = { const existingProcess = getProcessForPort(defaultPort);
type: 'confirm', const {shouldChangePort} = await prompts({
name: 'shouldChangePort', type: 'confirm',
message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${ name: 'shouldChangePort',
existingProcess ? ` Probably:\n ${existingProcess}` : '' message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${
} existingProcess ? ` Probably:\n ${existingProcess}` : ''
}
Would you like to run the app on another port instead?`), Would you like to run the app on another port instead?`),
initial: true, initial: true,
}; });
prompts(question).then((answer) => { return shouldChangePort ? port : null;
if (answer.shouldChangePort === true) { } catch (err) {
resolve(port); logger.error`Could not find an open port at ${host}.`;
} else { throw err;
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}".`}`,
);
},
);
} }

View file

@ -47,22 +47,19 @@ export default async function render(
): Promise<string> { ): Promise<string> {
try { try {
return await doRender(locals); return await doRender(locals);
} catch (e) { } catch (err) {
logger.error`Docusaurus Node/SSR could not render static page with path path=${ logger.error`Docusaurus server-side rendering could not render static page with path path=${locals.path}.`;
locals.path
} because of following error:
${(e as Error).stack!}`;
const isNotDefinedErrorRegex = const isNotDefinedErrorRegex =
/(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i; /(?: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. logger.info`It looks like you are using code that should run on the client-side only.
To get around it, try using code=${'<BrowserOnly>'} (path=${'https://docusaurus.io/docs/docusaurus-core/#browseronly'}) or code=${'ExecutionEnvironment'} (path=${'https://docusaurus.io/docs/docusaurus-core/#executionenvironment'}). To get around it, try using code=${'<BrowserOnly>'} (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).`; 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, useShortDoctype: true,
minifyJS: true, minifyJS: true,
}); });
} catch (e) { } catch (err) {
logger.error`Minification of page path=${ logger.error`Minification of page path=${locals.path} failed.`;
locals.path throw err;
} failed because of following error:
${(e as Error).stack!}`;
throw e;
} }
} }

View file

@ -56,9 +56,9 @@ export default async function build(
forceTerminate, forceTerminate,
isLastLocale, isLastLocale,
}); });
} catch (e) { } catch (err) {
logger.error`Unable to build website for locale name=${locale}.`; logger.error`Unable to build website for locale name=${locale}.`;
throw e; throw err;
} }
} }
const context = await loadContext(siteDir, { const context = await loadContext(siteDir, {

View file

@ -20,11 +20,9 @@ async function removePath(entry: {path: string; description: string}) {
try { try {
await fs.remove(entry.path); await fs.remove(entry.path);
logger.success`Removed the ${entry.description} at path=${entry.path}.`; logger.success`Removed the ${entry.description} at path=${entry.path}.`;
} catch (e) { } catch (err) {
logger.error`Could not remove the ${entry.description} at path=${ logger.error`Could not remove the ${entry.description} at path=${entry.path}.`;
entry.path logger.error(err);
}.
${e as string}`;
} }
} }

View file

@ -27,9 +27,9 @@ function shellExecLog(cmd: string) {
const result = shell.exec(cmd); const result = shell.exec(cmd);
logger.info`code=${obfuscateGitPass(cmd)} subdue=${`code: ${result.code}`}`; logger.info`code=${obfuscateGitPass(cmd)} subdue=${`code: ${result.code}`}`;
return result; return result;
} catch (e) { } catch (err) {
logger.error`code=${obfuscateGitPass(cmd)}`; 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 { try {
await fs.copy(fromPath, toPath); await fs.copy(fromPath, toPath);
} catch (error) { } catch (err) {
throw new Error( logger.error`Copying build assets from path=${fromPath} to path=${toPath} failed.`;
`Copying build assets from "${fromPath}" to "${toPath}" failed with error "${error}".`, throw err;
);
} }
shellExecLog('git add --all'); 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. // Build site, then push to deploymentBranch branch of specified repo.
try { try {
await runDeploy(await build(siteDir, cliOptions, false)); await runDeploy(await build(siteDir, cliOptions, false));
} catch (buildError) { } catch (err) {
logger.error((buildError as Error).message); logger.error('Deployment of the build output failed.');
process.exit(1); throw err;
} }
} else { } else {
// Push current build to deploymentBranch branch of specified repo. // Push current build to deploymentBranch branch of specified repo.

View file

@ -36,7 +36,7 @@ async function getExtraSourceCodeFilePaths(): Promise<string[]> {
require.resolve('@docusaurus/theme-common/lib'), require.resolve('@docusaurus/theme-common/lib'),
); );
return globSourceCodeFilePaths([themeCommonSourceDir]); return globSourceCodeFilePaths([themeCommonSourceDir]);
} catch (e) { } catch {
return []; // User may not use a Docusaurus official theme? Quite unlikely... return []; // User may not use a Docusaurus official theme? Quite unlikely...
} }
} }

View file

@ -162,7 +162,7 @@ export function getBrokenLinksErrorMessage(
async function isExistingFile(filePath: string) { async function isExistingFile(filePath: string) {
try { try {
return (await fs.stat(filePath)).isFile(); return (await fs.stat(filePath)).isFile();
} catch (e) { } catch {
return false; return false;
} }
} }

View file

@ -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`, 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; return value;
}, 'siteUrlCustomValidation'); }, 'siteUrlCustomValidation');

View file

@ -269,7 +269,9 @@ describe('writeTranslationFileContent', () => {
key1: {message: 'key1 message'}, key1: {message: 'key1 message'},
}, },
}), }),
).rejects.toThrowError(/Invalid translation file at/); ).rejects.toThrowErrorMatchingInlineSnapshot(
`"\\"bad\\" must be of type object"`,
);
}); });
}); });

View file

@ -57,10 +57,16 @@ const default => {
`, `,
}); });
const errorMock = jest.spyOn(console, 'error').mockImplementation();
await expect( await expect(
extractSourceCodeFileTranslations(sourceCodeFilePath, TestBabelOptions), extractSourceCodeFileTranslations(sourceCodeFilePath, TestBabelOptions),
).rejects.toThrowError( ).rejects.toThrow();
/Error while attempting to extract Docusaurus translations from source code file at path/,
expect(errorMock).toBeCalledWith(
expect.stringMatching(
/Error while attempting to extract Docusaurus translations from source code file at/,
),
); );
}); });

View file

@ -56,10 +56,9 @@ export async function readTranslationFileContent(
const content = JSON.parse(await fs.readFile(filePath, 'utf8')); const content = JSON.parse(await fs.readFile(filePath, 'utf8'));
ensureTranslationFileContent(content); ensureTranslationFileContent(content);
return content; return content;
} catch (e) { } catch (err) {
throw new Error( logger.error`Invalid translation file at path=${filePath}.`;
`Invalid translation file at ${filePath}.\n${(e as Error).message}`, throw err;
);
} }
} }
return undefined; return undefined;

View file

@ -166,11 +166,9 @@ export async function extractSourceCodeFileTranslations(
sourceCodeFilePath, sourceCodeFilePath,
); );
return translations; return translations;
} catch (e) { } catch (err) {
if (e instanceof Error) { logger.error`Error while attempting to extract Docusaurus translations from source code file at path=${sourceCodeFilePath}.`;
e.message = `Error while attempting to extract Docusaurus translations from source code file at path=${sourceCodeFilePath}\n${e.message}`; throw err;
}
throw e;
} }
} }

View file

@ -14,19 +14,17 @@ export async function getPackageJsonVersion(
): Promise<string | undefined> { ): Promise<string | undefined> {
if (await fs.pathExists(packageJsonPath)) { if (await fs.pathExists(packageJsonPath)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
const {version} = require(packageJsonPath); return require(packageJsonPath).version;
return typeof version === 'string' ? version : undefined;
} }
return undefined; return undefined;
} }
export async function getPackageJsonName( async function getPackageJsonName(
packageJsonPath: string, packageJsonPath: string,
): Promise<string | undefined> { ): Promise<string | undefined> {
if (await fs.pathExists(packageJsonPath)) { if (await fs.pathExists(packageJsonPath)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
const {name} = require(packageJsonPath); return require(packageJsonPath).name;
return typeof name === 'string' ? name : undefined;
} }
return undefined; return undefined;
} }

View file

@ -233,10 +233,10 @@ export default class CleanWebpackPlugin {
console.warn(`clean-webpack-plugin: removed ${filename}`); console.warn(`clean-webpack-plugin: removed ${filename}`);
}); });
} }
} catch (error) { } catch (err) {
const needsForce = const needsForce =
/Cannot delete files\/folders outside the current working directory\./.test( /Cannot delete files\/folders outside the current working directory\./.test(
(error as Error).message, (err as Error).message,
); );
if (needsForce) { if (needsForce) {
@ -246,7 +246,7 @@ export default class CleanWebpackPlugin {
throw new Error(message); throw new Error(message);
} }
throw error; throw err;
} }
} }
} }

View file

@ -17,6 +17,7 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@docusaurus/logger": "2.0.0-beta.15",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"node-vibrant": "^3.1.6", "node-vibrant": "^3.1.6",

View file

@ -71,8 +71,8 @@ export default async function lqipLoader(
} else { } else {
callback(new Error('ERROR'), undefined); callback(new Error('ERROR'), undefined);
} }
} catch (error) { } catch (err) {
console.error(error); console.error(err);
callback(new Error('ERROR'), undefined); callback(new Error('ERROR'), undefined);
} }
} }

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import logger from '@docusaurus/logger';
import Vibrant from 'node-vibrant'; import Vibrant from 'node-vibrant';
import path from 'path'; import path from 'path';
import sharp from 'sharp'; import sharp from 'sharp';
@ -22,29 +23,29 @@ const SUPPORTED_MIMES: Record<string, string> = {
}; };
export async function base64(file: string): Promise<string> { export async function base64(file: string): Promise<string> {
let extension = path.extname(file) || ''; let extension = path.extname(file);
extension = extension.split('.').pop()!; extension = extension.split('.').pop()!;
if (!SUPPORTED_MIMES[extension]) { if (!SUPPORTED_MIMES[extension]) {
throw new Error(ERROR_EXT); throw new Error(ERROR_EXT);
} }
const data = await sharp(file).resize(10).toBuffer(); try {
if (data) { const data = await sharp(file).resize(10).toBuffer();
return toBase64(SUPPORTED_MIMES[extension], data); 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<string[]> { export async function palette(file: string): Promise<string[]> {
const vibrant = new Vibrant(file, {}); const vibrant = new Vibrant(file, {});
const pal = await vibrant.getPalette(); try {
if (pal) { const pal = await vibrant.getPalette();
return toPalette(pal); 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;
});

View file

@ -90,6 +90,7 @@ goss
goyal goyal
gtag gtag
héctor héctor
heuristical
hideable hideable
hola hola
horiz horiz
@ -227,13 +228,13 @@ roadmap
rocketvalidator rocketvalidator
rtcts rtcts
rtlcss rtlcss
sàáâãäåçèéêëìíîïðòóôõöùúûüýÿ
scaleway scaleway
searchbar searchbar
sebastien sebastien
sébastien sébastien
sebastienlorber sebastienlorber
sensical sensical
serializers
setaf setaf
sida sida
simen simen