refactor(v2): cleanup console output (#4979)

* refactor(v2): cleanup console output

* fix jest issue

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Alexey Pyltsyn 2021-06-16 12:37:28 +03:00 committed by GitHub
parent 8501db78a1
commit 41d9288e3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
86 changed files with 382 additions and 339 deletions

View file

@ -18,9 +18,9 @@ const requiredVersion = require('../package.json').engines.node;
if (!semver.satisfies(process.version, requiredVersion)) { if (!semver.satisfies(process.version, requiredVersion)) {
console.log( console.log(
chalk.red(`\nMinimum node version not met :)`) + chalk.red(`\nMinimum Node.js version not met :)`) +
chalk.yellow( chalk.yellow(
`\nYou are using Node ${process.version}, Requirement: Node ${requiredVersion}.\n`, `\nYou are using Node.js ${process.version}, Requirement: Node.js ${requiredVersion}.\n`,
), ),
); );
process.exit(1); process.exit(1);
@ -42,7 +42,7 @@ program
.command('init [siteName] [template] [rootDir]') .command('init [siteName] [template] [rootDir]')
.option('--use-npm') .option('--use-npm')
.option('--skip-install') .option('--skip-install')
.description('Initialize website') .description('Initialize website.')
.action((siteName, template, rootDir = '.', {useNpm, skipInstall}) => { .action((siteName, template, rootDir = '.', {useNpm, skipInstall}) => {
wrapCommand(init)(path.resolve(rootDir), siteName, template, { wrapCommand(init)(path.resolve(rootDir), siteName, template, {
useNpm, useNpm,

View file

@ -76,12 +76,12 @@ export default async function init(
} }
if (!name) { if (!name) {
throw new Error(chalk.red('A site name is required')); throw new Error(chalk.red('A website name is required.'));
} }
const dest = path.resolve(rootDir, name); const dest = path.resolve(rootDir, name);
if (fs.existsSync(dest)) { if (fs.existsSync(dest)) {
throw new Error(`Directory already exists at ${dest} !`); throw new Error(`Directory already exists at "${dest}"!`);
} }
let template = reqTemplate; let template = reqTemplate;
@ -108,7 +108,7 @@ export default async function init(
return chalk.red(`Invalid repository URL`); return chalk.red(`Invalid repository URL`);
}, },
message: message:
'Enter a repository URL from GitHub, BitBucket, GitLab, or any other public repo. \n(e.g: https://github.com/ownerName/repoName.git)', 'Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.\n(e.g: https://github.com/ownerName/repoName.git)',
}); });
template = repoPrompt.gitRepoUrl; template = repoPrompt.gitRepoUrl;
} }
@ -118,12 +118,12 @@ export default async function init(
console.log(); console.log();
if (template && isValidGitRepoUrl(template)) { if (template && isValidGitRepoUrl(template)) {
console.log(`Cloning Git template: ${chalk.cyan(template)}`); console.log(`Cloning Git template ${chalk.cyan(template)}...`);
if ( if (
shell.exec(`git clone --recursive ${template} ${dest}`, {silent: true}) shell.exec(`git clone --recursive ${template} ${dest}`, {silent: true})
.code !== 0 .code !== 0
) { ) {
throw new Error(chalk.red(`Cloning Git template: ${template} failed!`)); throw new Error(chalk.red(`Cloning Git template ${template} failed!`));
} }
} else if (template && templates.includes(template)) { } else if (template && templates.includes(template)) {
// Docusaurus templates. // Docusaurus templates.
@ -131,12 +131,12 @@ export default async function init(
await fs.copy(path.resolve(templatesDir, template), dest); await fs.copy(path.resolve(templatesDir, template), dest);
} catch (err) { } catch (err) {
console.log( console.log(
`Copying Docusaurus template: ${chalk.cyan(template)} failed!`, `Copying Docusaurus template ${chalk.cyan(template)} failed!`,
); );
throw err; throw err;
} }
} else { } else {
throw new Error('Invalid template'); throw new Error('Invalid template.');
} }
// Update package.json info. // Update package.json info.
@ -147,7 +147,7 @@ export default async function init(
private: true, private: true,
}); });
} catch (err) { } catch (err) {
console.log(chalk.red('Failed to update package.json')); console.log(chalk.red('Failed to update package.json.'));
throw err; throw err;
} }
@ -164,12 +164,12 @@ export default async function init(
const pkgManager = useYarn ? 'yarn' : 'npm'; const pkgManager = useYarn ? 'yarn' : 'npm';
if (!cliOptions.skipInstall) { if (!cliOptions.skipInstall) {
console.log(`Installing dependencies with: ${chalk.cyan(pkgManager)}`); console.log(`Installing dependencies with ${chalk.cyan(pkgManager)}...`);
try { try {
shell.exec(`cd "${name}" && ${useYarn ? 'yarn' : 'npm install'}`); shell.exec(`cd "${name}" && ${useYarn ? 'yarn' : 'npm install'}`);
} catch (err) { } catch (err) {
console.log(chalk.red('Installation failed')); console.log(chalk.red('Installation failed.'));
throw err; throw err;
} }
} }
@ -182,23 +182,26 @@ export default async function init(
: path.relative(process.cwd(), name); : path.relative(process.cwd(), name);
console.log(); console.log();
console.log(`Success! Created ${chalk.cyan(cdpath)}`); console.log(`Successfully created "${chalk.cyan(cdpath)}".`);
console.log('Inside that directory, you can run several commands:'); console.log('Inside that directory, you can run several commands:');
console.log(); console.log();
console.log(chalk.cyan(` ${pkgManager} start`)); console.log(chalk.cyan(` ${pkgManager} start`));
console.log(' Starts the development server.'); console.log(' Starts the development server.');
console.log(); console.log();
console.log(chalk.cyan(` ${pkgManager} ${useYarn ? '' : 'run '}build`)); console.log(chalk.cyan(` ${pkgManager} ${useYarn ? '' : 'run '}build`));
console.log(' Bundles the app into static files for production.'); console.log(' Bundles your website into static files for production.');
console.log();
console.log(chalk.cyan(` ${pkgManager} ${useYarn ? '' : 'run '}serve`));
console.log(' Serve the built website locally.');
console.log(); console.log();
console.log(chalk.cyan(` ${pkgManager} deploy`)); console.log(chalk.cyan(` ${pkgManager} deploy`));
console.log(' Publish website to GitHub pages.'); console.log(' Publish the website to GitHub pages.');
console.log(); console.log();
console.log('We suggest that you begin by typing:'); console.log('We recommend that you begin by typing:');
console.log(); console.log();
console.log(chalk.cyan(' cd'), cdpath); console.log(chalk.cyan(' cd'), cdpath);
console.log(` ${chalk.cyan(`${pkgManager} start`)}`); console.log(` ${chalk.cyan(`${pkgManager} start`)}`);
console.log(); console.log();
console.log('Happy hacking!'); console.log('Happy building awesome websites!');
} }

View file

@ -2,7 +2,7 @@
exports[`transformImage plugin fail if image does not exist 1`] = `"Image packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/fixtures/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/img/doesNotExist.png used in packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/fixtures/fail.md not found."`;
exports[`transformImage plugin fail if image url is absent 1`] = `"Markdown image url is mandatory. filePath=packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/fixtures/noUrl.md"`; exports[`transformImage plugin fail if image url is absent 1`] = `"Markdown image URL is mandatory in \\"packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/fixtures/noUrl.md\\" file"`;
exports[`transformImage plugin pathname protocol 1`] = ` exports[`transformImage plugin pathname protocol 1`] = `
"![img](/img/unchecked.png) "![img](/img/unchecked.png)

View file

@ -57,9 +57,9 @@ async function ensureImageFileExist(imagePath, sourceFilePath) {
async function processImageNode(node, {filePath, staticDir}) { async function processImageNode(node, {filePath, staticDir}) {
if (!node.url) { if (!node.url) {
throw new Error( throw new Error(
`Markdown image url is mandatory. filePath=${toMessageRelativeFilePath( `Markdown image URL is mandatory in "${toMessageRelativeFilePath(
filePath, filePath,
)}`, )}" file`,
); );
} }

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`transformAsset plugin fail if asset url is absent 1`] = `"Markdown link url is mandatory. filePath=packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/noUrl.md, title=asset, line=1"`; exports[`transformAsset plugin fail if asset url is absent 1`] = `"Markdown link URL is mandatory in \\"packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/noUrl.md\\" file (title: asset, line: 1)."`;
exports[`transformAsset plugin pathname protocol 1`] = ` exports[`transformAsset plugin pathname protocol 1`] = `
"[asset](pathname:///asset/unchecked.pdf) "[asset](pathname:///asset/unchecked.pdf)

View file

@ -111,9 +111,9 @@ async function processLinkNode({node, _index, _parent, filePath, staticDir}) {
const line = const line =
(node.position && node.position.start && node.position.start.line) || '?'; (node.position && node.position.start && node.position.start.line) || '?';
throw new Error( throw new Error(
`Markdown link url is mandatory. filePath=${toMessageRelativeFilePath( `Markdown link URL is mandatory in "${toMessageRelativeFilePath(
filePath, filePath,
)}, title=${title}, line=${line}`, )}" file (title: ${title}, line: ${line}).`,
); );
} }

View file

@ -28,9 +28,9 @@ function wrapCommand(fn) {
if (!semver.satisfies(process.version, requiredVersion)) { if (!semver.satisfies(process.version, requiredVersion)) {
console.log( console.log(
chalk.red(`\nMinimum Node version not met :(`) + chalk.red(`\nMinimum Node.js version not met :(`) +
chalk.yellow( chalk.yellow(
`\n\nYou are using Node ${process.version}. We require Node ${requiredVersion} or up!\n`, `\n\nYou are using Node ${process.version}. We require Node.js ${requiredVersion} or up!\n`,
), ),
); );
process.exit(1); process.exit(1);
@ -38,9 +38,9 @@ if (!semver.satisfies(process.version, requiredVersion)) {
cli cli
.command('migrate [siteDir] [newDir]') .command('migrate [siteDir] [newDir]')
.option('--mdx', 'Try to migrate MD to MDX too') .option('--mdx', 'try to migrate MD to MDX too')
.option('--page', 'Try to migrate pages too') .option('--page', 'try to migrate pages too')
.description('Migrate between versions of docusaurus website') .description('Migrate between versions of Docusaurus website.')
.action((siteDir = '.', newDir = '.', {mdx, page}) => { .action((siteDir = '.', newDir = '.', {mdx, page}) => {
const sitePath = path.resolve(siteDir); const sitePath = path.resolve(siteDir);
const newSitePath = path.resolve(newDir); const newSitePath = path.resolve(newDir);
@ -49,7 +49,7 @@ cli
cli cli
.command('mdx [siteDir] [newDir]') .command('mdx [siteDir] [newDir]')
.description('Migrate markdown files to MDX') .description('Migrate markdown files to MDX.')
.action((siteDir = '.', newDir = '.') => { .action((siteDir = '.', newDir = '.') => {
const sitePath = path.resolve(siteDir); const sitePath = path.resolve(siteDir);
const newSitePath = path.resolve(newDir); const newSitePath = path.resolve(newDir);

View file

@ -20,8 +20,8 @@ exports[`collectRedirects should throw if redirect creator creates array of arra
exports[`collectRedirects should throw if redirect creator creates invalid redirects 1`] = ` exports[`collectRedirects should throw if redirect creator creates invalid redirects 1`] = `
"Some created redirects are invalid: "Some created redirects are invalid:
- {\\"from\\":\\"https://google.com/\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string - {\\"from\\":\\"https://google.com/\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string.
- {\\"from\\":\\"//abc\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string - {\\"from\\":\\"//abc\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string.
- {\\"from\\":\\"/def?queryString=toto\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string - {\\"from\\":\\"/def?queryString=toto\\",\\"to\\":\\"/\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string.
" "
`; `;

View file

@ -1,10 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`validateRedirect throw for bad redirects 1`] = `"{\\"from\\":\\"https://fb.com/fromSomePath\\",\\"to\\":\\"/toSomePath\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string"`; exports[`validateRedirect throw for bad redirects 1`] = `"{\\"from\\":\\"https://fb.com/fromSomePath\\",\\"to\\":\\"/toSomePath\\"} => Validation error: \\"from\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string."`;
exports[`validateRedirect throw for bad redirects 2`] = `"{\\"from\\":\\"/fromSomePath\\",\\"to\\":\\"https://fb.com/toSomePath\\"} => Validation error: \\"to\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string"`; exports[`validateRedirect throw for bad redirects 2`] = `"{\\"from\\":\\"/fromSomePath\\",\\"to\\":\\"https://fb.com/toSomePath\\"} => Validation error: \\"to\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string."`;
exports[`validateRedirect throw for bad redirects 3`] = `"{\\"from\\":\\"/fromSomePath\\",\\"to\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: \\"to\\" is not a valid pathname. Pathname should start with / and not contain any domain or query string"`; exports[`validateRedirect throw for bad redirects 3`] = `"{\\"from\\":\\"/fromSomePath\\",\\"to\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: \\"to\\" is not a valid pathname. Pathname should start with slash and not contain any domain or query string."`;
exports[`validateRedirect throw for bad redirects 4`] = `"{\\"from\\":null,\\"to\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: \\"from\\" must be a string"`; exports[`validateRedirect throw for bad redirects 4`] = `"{\\"from\\":null,\\"to\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: \\"from\\" must be a string"`;

View file

@ -9,46 +9,43 @@ import {
createFromExtensionsRedirects, createFromExtensionsRedirects,
createToExtensionsRedirects, createToExtensionsRedirects,
} from '../extensionRedirects'; } from '../extensionRedirects';
import {RedirectMetadata} from '../types';
const createExtensionValidationTests = (
extensionRedirectCreatorFn: (
paths: string[],
extensions: string[],
) => RedirectMetadata[],
) => {
test('should reject empty extensions', () => {
expect(() => {
extensionRedirectCreatorFn(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(
`"Extension=['.html'] contains a . (dot) and is not allowed. If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the 'createRedirects' plugin option."`,
);
});
test('should reject extensions with .', () => {
expect(() => {
extensionRedirectCreatorFn(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(
`"Extension=['.html'] contains a . (dot) and is not allowed. If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the 'createRedirects' plugin option."`,
);
});
test('should reject extensions with /', () => {
expect(() => {
extensionRedirectCreatorFn(['/'], ['ht/ml']);
}).toThrowErrorMatchingInlineSnapshot(
`"Extension=['ht/ml'] contains a / and is not allowed. If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the 'createRedirects' plugin option."`,
);
});
test('should reject extensions with illegal url char', () => {
expect(() => {
extensionRedirectCreatorFn(['/'], [',']);
}).toThrowErrorMatchingInlineSnapshot(
`"Extension=[','] contains invalid uri characters. If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the 'createRedirects' plugin option."`,
);
});
};
describe('createToExtensionsRedirects', () => { describe('createToExtensionsRedirects', () => {
createExtensionValidationTests(createToExtensionsRedirects); test('should reject empty extensions', () => {
expect(() => {
createToExtensionsRedirects(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\".html\\" contains a \\".\\" (dot) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with .', () => {
expect(() => {
createToExtensionsRedirects(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\".html\\" contains a \\".\\" (dot) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with /', () => {
expect(() => {
createToExtensionsRedirects(['/'], ['ht/ml']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\"ht/ml\\" contains a \\"/\\" (slash) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with illegal url char', () => {
expect(() => {
createToExtensionsRedirects(['/'], [',']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\",\\" contains invalid URI characters.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should create redirects from html/htm extensions', () => { test('should create redirects from html/htm extensions', () => {
const ext = ['html', 'htm']; const ext = ['html', 'htm'];
@ -78,7 +75,41 @@ describe('createToExtensionsRedirects', () => {
}); });
describe('createFromExtensionsRedirects', () => { describe('createFromExtensionsRedirects', () => {
createExtensionValidationTests(createFromExtensionsRedirects); test('should reject empty extensions', () => {
expect(() => {
createFromExtensionsRedirects(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\".html\\" contains a \\".\\" (dot) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with .', () => {
expect(() => {
createFromExtensionsRedirects(['/'], ['.html']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\".html\\" contains a \\".\\" (dot) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with /', () => {
expect(() => {
createFromExtensionsRedirects(['/'], ['ht/ml']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\"ht/ml\\" contains a \\"/\\" (slash) which is not allowed.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should reject extensions with illegal url char', () => {
expect(() => {
createFromExtensionsRedirects(['/'], [',']);
}).toThrowErrorMatchingInlineSnapshot(`
"Extension \\",\\" contains invalid URI characters.
If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the \\"createRedirects\\" plugin option."
`);
});
test('should create redirects to html/htm extensions', () => { test('should create redirects to html/htm extensions', () => {
const ext = ['html', 'htm']; const ext = ['html', 'htm'];

View file

@ -140,7 +140,7 @@ describe('writeRedirectFiles', () => {
); );
await expect(writeRedirectFiles(filesMetadata)).rejects.toThrowError( await expect(writeRedirectFiles(filesMetadata)).rejects.toThrowError(
`Redirect file creation error for path=${filesMetadata[0].fileAbsolutePath}: Error: The redirect plugin is not supposed to override existing files`, `Redirect file creation error for "${filesMetadata[0].fileAbsolutePath}" path: Error: The redirect plugin is not supposed to override existing files.`,
); );
}); });
}); });

View file

@ -10,29 +10,27 @@ import {removeSuffix} from '@docusaurus/utils';
import {RedirectMetadata} from './types'; import {RedirectMetadata} from './types';
const ExtensionAdditionalMessage = const ExtensionAdditionalMessage =
"If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the 'createRedirects' plugin option."; 'If the redirect extension system is not good enough for your usecase, you can create redirects yourself with the "createRedirects" plugin option.';
const validateExtension = (ext: string) => { const validateExtension = (ext: string) => {
if (!ext) { if (!ext) {
throw new Error( throw new Error(
`Extension=['${String( `Extension "${ext}" is not allowed.\n${ExtensionAdditionalMessage}`,
ext,
)}'] is not allowed. ${ExtensionAdditionalMessage}`,
); );
} }
if (ext.includes('.')) { if (ext.includes('.')) {
throw new Error( throw new Error(
`Extension=['${ext}'] contains a . (dot) and is not allowed. ${ExtensionAdditionalMessage}`, `Extension "${ext}" contains a "." (dot) which is not allowed.\n${ExtensionAdditionalMessage}`,
); );
} }
if (ext.includes('/')) { if (ext.includes('/')) {
throw new Error( throw new Error(
`Extension=['${ext}'] contains a / and is not allowed. ${ExtensionAdditionalMessage}`, `Extension "${ext}" contains a "/" (slash) which is not allowed.\n${ExtensionAdditionalMessage}`,
); );
} }
if (encodeURIComponent(ext) !== ext) { if (encodeURIComponent(ext) !== ext) {
throw new Error( throw new Error(
`Extension=['${ext}'] contains invalid uri characters. ${ExtensionAdditionalMessage}`, `Extension "${ext}" contains invalid URI characters.\n${ExtensionAdditionalMessage}`,
); );
} }
}; };

View file

@ -59,7 +59,7 @@ export async function writeRedirectFile(
// User-friendly security to prevent file overrides // User-friendly security to prevent file overrides
if (await fs.pathExists(file.fileAbsolutePath)) { if (await fs.pathExists(file.fileAbsolutePath)) {
throw new Error( throw new Error(
'The redirect plugin is not supposed to override existing files', 'The redirect plugin is not supposed to override existing files.',
); );
} }
await fs.ensureDir(path.dirname(file.fileAbsolutePath)); await fs.ensureDir(path.dirname(file.fileAbsolutePath));
@ -72,7 +72,7 @@ export async function writeRedirectFile(
); );
} catch (err) { } catch (err) {
throw new Error( throw new Error(
`Redirect file creation error for path=${file.fileAbsolutePath}: ${err}`, `Redirect file creation error for "${file.fileAbsolutePath}" path: ${err}.`,
); );
} }
} }

View file

@ -62,7 +62,7 @@ export async function generateBlogFeed(
): Promise<Feed | null> { ): Promise<Feed | null> {
if (!options.feedOptions) { if (!options.feedOptions) {
throw new Error( throw new Error(
'Invalid options - `feedOptions` is not expected to be null.', 'Invalid options: "feedOptions" is not expected to be null.',
); );
} }
const {siteConfig} = context; const {siteConfig} = context;
@ -160,7 +160,7 @@ export async function generateBlogPosts(
if (frontMatter.id) { if (frontMatter.id) {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
`${blogFileName} - 'id' header option is deprecated. Please use 'slug' option instead.`, `"id" header option is deprecated in ${blogFileName} file. Please use "slug" option instead.`,
), ),
); );
} }

View file

@ -500,7 +500,7 @@ export default function pluginContentBlog(
try { try {
await fs.outputFile(feedPath, feedContent); await fs.outputFile(feedPath, feedContent);
} catch (err) { } catch (err) {
throw new Error(`Generating ${feedType} feed failed: ${err}`); throw new Error(`Generating ${feedType} feed failed: ${err}.`);
} }
}), }),
); );

View file

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`sidebar site with wrong sidebar content 1`] = ` exports[`sidebar site with wrong sidebar content 1`] = `
"Bad sidebar file at 'packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json'. "Invalid sidebar file at \\"packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json\\".
These sidebar document ids do not exist: These sidebar document ids do not exist:
- goku, - goku
Available document ids= Available document ids are:
- foo/bar - foo/bar
- foo/baz - foo/baz
- headingAsTitle - headingAsTitle

View file

@ -35,7 +35,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0"`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -45,7 +45,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0"`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -55,7 +55,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0"`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
}); });
@ -68,7 +68,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Do not include slash (/) or (\\\\). Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -78,7 +78,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Do not include slash (/) or (\\\\). Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\\\). Try something like: 1.0.0."`,
); );
}); });
@ -91,7 +91,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Length must <= 32 characters. Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Length cannot exceed 32 characters. Try something like: 1.0.0."`,
); );
}); });
@ -104,7 +104,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -114,7 +114,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`,
); );
}); });
@ -127,7 +127,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -137,7 +137,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
expect(() => expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(
@ -147,7 +147,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0"`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
}); });
@ -160,7 +160,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] This version already exists!. Use a version tag that does not already exist."`, `"[docs]: this version already exists! Use a version tag that does not already exist."`,
); );
}); });
@ -174,7 +174,7 @@ describe('docsVersion', () => {
DEFAULT_OPTIONS, DEFAULT_OPTIONS,
), ),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"[docs] There is no docs to version !"`, `"[docs]: there is no docs to version!"`,
); );
}); });
@ -218,7 +218,7 @@ describe('docsVersion', () => {
getVersionsFilePath(simpleSiteDir, DEFAULT_PLUGIN_ID), getVersionsFilePath(simpleSiteDir, DEFAULT_PLUGIN_ID),
); );
expect(versions).toEqual(['1.0.0']); expect(versions).toEqual(['1.0.0']);
expect(consoleMock).toHaveBeenCalledWith('[docs] Version 1.0.0 created!'); expect(consoleMock).toHaveBeenCalledWith('[docs]: version 1.0.0 created!');
copyMock.mockRestore(); copyMock.mockRestore();
writeMock.mockRestore(); writeMock.mockRestore();
@ -271,7 +271,7 @@ describe('docsVersion', () => {
getVersionsFilePath(versionedSiteDir, DEFAULT_PLUGIN_ID), getVersionsFilePath(versionedSiteDir, DEFAULT_PLUGIN_ID),
); );
expect(versions).toEqual(['2.0.0', '1.0.1', '1.0.0', 'withSlugs']); expect(versions).toEqual(['2.0.0', '1.0.1', '1.0.0', 'withSlugs']);
expect(consoleMock).toHaveBeenCalledWith('[docs] Version 2.0.0 created!'); expect(consoleMock).toHaveBeenCalledWith('[docs]: version 2.0.0 created!');
copyMock.mockRestore(); copyMock.mockRestore();
writeMock.mockRestore(); writeMock.mockRestore();
@ -322,7 +322,7 @@ describe('docsVersion', () => {
); );
expect(versions).toEqual(['2.0.0', '1.0.0']); expect(versions).toEqual(['2.0.0', '1.0.0']);
expect(consoleMock).toHaveBeenCalledWith( expect(consoleMock).toHaveBeenCalledWith(
'[community] Version 2.0.0 created!', '[community]: version 2.0.0 created!',
); );
copyMock.mockRestore(); copyMock.mockRestore();

View file

@ -453,7 +453,7 @@ describe('simple site', () => {
}), }),
); );
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"Document id [Hello/world] cannot include \\"/\\"."`, `"Document id \\"Hello/world\\" cannot include slash."`,
); );
}); });

View file

@ -44,8 +44,10 @@ function getDocById(version: LoadedVersion, unversionedId: string) {
const doc = findDocById(version, unversionedId); const doc = findDocById(version, unversionedId);
if (!doc) { if (!doc) {
throw new Error( throw new Error(
`No doc found with id=${unversionedId} in version ${version.versionName}. `No doc found with id "${unversionedId}" in version ${
Available ids=\n- ${version.docs.map((d) => d.unversionedId).join('\n- ')}`, version.versionName
}.
Available ids are:\n- ${version.docs.map((d) => d.unversionedId).join('\n- ')}`,
); );
} }
return doc; return doc;
@ -85,7 +87,7 @@ const createFakeActions = (contentDir: string) => {
key.startsWith(prefix), key.startsWith(prefix),
); );
if (!entry) { if (!entry) {
throw new Error(`No created entry found for prefix=[${prefix}] throw new Error(`No created entry found for prefix "${prefix}".
Entries created: Entries created:
- ${Object.keys(dataContainer).join('\n- ')} - ${Object.keys(dataContainer).join('\n- ')}
`); `);
@ -151,8 +153,8 @@ describe('sidebar', () => {
); );
await plugin.loadContent!(); await plugin.loadContent!();
}).rejects.toThrowErrorMatchingInlineSnapshot(` }).rejects.toThrowErrorMatchingInlineSnapshot(`
"The path to the sidebar file does not exist at [wrong-path-sidebar.json]. "The path to the sidebar file does not exist at \\"wrong-path-sidebar.json\\".
Please set the docs [sidebarPath] field in your config file to: Please set the docs \\"sidebarPath\\" field in your config file to:
- a sidebars path that exists - a sidebars path that exists
- false: to disable the sidebar - false: to disable the sidebar
- undefined: for Docusaurus generates it automatically" - undefined: for Docusaurus generates it automatically"
@ -217,7 +219,7 @@ describe('empty/no docs website', () => {
await expect( await expect(
plugin.loadContent!(), plugin.loadContent!(),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"Docs version current has no docs! At least one doc should exist at path=[docs]"`, `"Docs version \\"current\\" has no docs! At least one doc should exist at \\"docs\\"."`,
); );
}); });
@ -231,11 +233,11 @@ describe('empty/no docs website', () => {
}), }),
), ),
).toThrowError( ).toThrowError(
`The docs folder does not exist for version [current]. A docs folder is expected to be found at ${ `The docs folder does not exist for version "current". A docs folder is expected to be found at ${
process.platform === 'win32' process.platform === 'win32'
? 'path\\doesnt\\exist' ? 'path\\doesnt\\exist'
: 'path/doesnt/exist' : 'path/doesnt/exist'
}`, }.`,
); );
}); });
}); });

View file

@ -60,7 +60,7 @@ describe('loadSidebars', () => {
'sidebars-category-wrong-items.json', 'sidebars-category-wrong-items.json',
); );
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"type\\":\\"category\\",\\"label\\":\\"Category Label\\",\\"items\\":\\"doc1\\"}. \\"items\\" must be an array."`, `"Error loading {\\"type\\":\\"category\\",\\"label\\":\\"Category Label\\",\\"items\\":\\"doc1\\"}: \\"items\\" must be an array."`,
); );
}); });
@ -70,7 +70,7 @@ describe('loadSidebars', () => {
'sidebars-category-wrong-label.json', 'sidebars-category-wrong-label.json',
); );
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"type\\":\\"category\\",\\"label\\":true,\\"items\\":[\\"doc1\\"]}. \\"label\\" must be a string."`, `"Error loading {\\"type\\":\\"category\\",\\"label\\":true,\\"items\\":[\\"doc1\\"]}: \\"label\\" must be a string."`,
); );
}); });
@ -80,7 +80,7 @@ describe('loadSidebars', () => {
'sidebars-doc-id-not-string.json', 'sidebars-doc-id-not-string.json',
); );
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"type\\":\\"doc\\",\\"id\\":[\\"doc1\\"]}. \\"id\\" must be a string."`, `"Error loading {\\"type\\":\\"doc\\",\\"id\\":[\\"doc1\\"]}: \\"id\\" must be a string."`,
); );
}); });
@ -102,22 +102,23 @@ describe('loadSidebars', () => {
test('sidebars link wrong label', async () => { test('sidebars link wrong label', async () => {
const sidebarPath = path.join(fixtureDir, 'sidebars-link-wrong-label.json'); const sidebarPath = path.join(fixtureDir, 'sidebars-link-wrong-label.json');
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"type\\":\\"link\\",\\"label\\":false,\\"href\\":\\"https://github.com\\"}. \\"label\\" must be a string."`, `"Error loading {\\"type\\":\\"link\\",\\"label\\":false,\\"href\\":\\"https://github.com\\"}: \\"label\\" must be a string."`,
); );
}); });
test('sidebars link wrong href', async () => { test('sidebars link wrong href', async () => {
const sidebarPath = path.join(fixtureDir, 'sidebars-link-wrong-href.json'); const sidebarPath = path.join(fixtureDir, 'sidebars-link-wrong-href.json');
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"type\\":\\"link\\",\\"label\\":\\"GitHub\\",\\"href\\":[\\"example.com\\"]}. \\"href\\" must be a string."`, `"Error loading {\\"type\\":\\"link\\",\\"label\\":\\"GitHub\\",\\"href\\":[\\"example.com\\"]}: \\"href\\" must be a string."`,
); );
}); });
test('sidebars with unknown sidebar item type', async () => { test('sidebars with unknown sidebar item type', async () => {
const sidebarPath = path.join(fixtureDir, 'sidebars-unknown-type.json'); const sidebarPath = path.join(fixtureDir, 'sidebars-unknown-type.json');
expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars(sidebarPath)).toThrowErrorMatchingInlineSnapshot(`
`"Unknown sidebar item type [superman]. Sidebar item={\\"type\\":\\"superman\\"} "`, "Unknown sidebar item type \\"superman\\". Sidebar item is {\\"type\\":\\"superman\\"}.
); "
`);
}); });
test('sidebars with known sidebar item type but wrong field', async () => { test('sidebars with known sidebar item type but wrong field', async () => {

View file

@ -174,7 +174,7 @@ describe('simple site', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Bad docs options.versions: unknown versions found: unknownVersionName1,unknownVersionName2. Available version names are: current"`, `"Invalid docs option \\"versions\\": unknown versions (unknownVersionName1,unknownVersionName2) found. Available version names are: current"`,
); );
}); });
@ -187,7 +187,7 @@ describe('simple site', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Docs: using disableVersioning=true option on a non-versioned site does not make sense"`, `"Docs: using \\"disableVersioning=true\\" option on a non-versioned site does not make sense."`,
); );
}); });
@ -200,7 +200,7 @@ describe('simple site', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"It is not possible to use docs without any version. Please check the configuration of these options: includeCurrentVersion=false disableVersioning=false"`, `"It is not possible to use docs without any version. Please check the configuration of these options: \\"includeCurrentVersion=false\\", \\"disableVersioning=false\\"."`,
); );
}); });
}); });
@ -527,7 +527,7 @@ describe('versioned site, pluginId=default', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"It is not possible to use docs without any version. Please check the configuration of these options: includeCurrentVersion=false disableVersioning=true"`, `"It is not possible to use docs without any version. Please check the configuration of these options: \\"includeCurrentVersion=false\\", \\"disableVersioning=true\\"."`,
); );
}); });
@ -543,7 +543,7 @@ describe('versioned site, pluginId=default', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Bad docs options.onlyIncludeVersions: an empty array is not allowed, at least one version is needed"`, `"Invalid docs option \\"onlyIncludeVersions\\": an empty array is not allowed, at least one version is needed."`,
); );
}); });
@ -559,7 +559,7 @@ describe('versioned site, pluginId=default', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Bad docs options.onlyIncludeVersions: unknown versions found: unknownVersion1,unknownVersion2. Available version names are: current, 1.0.1, 1.0.0, withSlugs"`, `"Invalid docs option \\"onlyIncludeVersions\\": unknown versions (unknownVersion1,unknownVersion2) found. Available version names are: current, 1.0.1, 1.0.0, withSlugs"`,
); );
}); });
@ -576,7 +576,7 @@ describe('versioned site, pluginId=default', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Bad docs options.lastVersion: if you use both the onlyIncludeVersions and lastVersion options, then lastVersion must be present in the provided onlyIncludeVersions array"`, `"Invalid docs option \\"lastVersion\\": if you use both the \\"onlyIncludeVersions\\" and \\"lastVersion\\" options, then \\"lastVersion\\" must be present in the provided \\"onlyIncludeVersions\\" array."`,
); );
}); });
@ -595,7 +595,7 @@ describe('versioned site, pluginId=default', () => {
context: defaultContext, context: defaultContext,
}); });
}).toThrowErrorMatchingInlineSnapshot( }).toThrowErrorMatchingInlineSnapshot(
`"The versions file should contain an array of versions! Found content={\\"invalid\\":\\"json\\"}"`, `"The versions file should contain an array of versions! Found content: {\\"invalid\\":\\"json\\"}"`,
); );
mock.mockRestore(); mock.mockRestore();
}); });
@ -712,7 +712,7 @@ describe('versioned site, pluginId=community', () => {
context: defaultContext, context: defaultContext,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"It is not possible to use docs without any version. Please check the configuration of these options: includeCurrentVersion=false disableVersioning=true"`, `"It is not possible to use docs without any version. Please check the configuration of these options: \\"includeCurrentVersion=false\\", \\"disableVersioning=true\\"."`,
); );
}); });
}); });

View file

@ -96,19 +96,19 @@ export function cliDocsVersionCommand(
if (!version) { if (!version) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0`, `${pluginIdLogPrefix}: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0.`,
); );
} }
if (version.includes('/') || version.includes('\\')) { if (version.includes('/') || version.includes('\\')) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}Invalid version tag specified! Do not include slash (/) or (\\). Try something like: 1.0.0`, `${pluginIdLogPrefix}: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.`,
); );
} }
if (version.length > 32) { if (version.length > 32) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}Invalid version tag specified! Length must <= 32 characters. Try something like: 1.0.0`, `${pluginIdLogPrefix}: invalid version tag specified! Length cannot exceed 32 characters. Try something like: 1.0.0.`,
); );
} }
@ -117,13 +117,13 @@ export function cliDocsVersionCommand(
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
if (/[<>:"|?*\x00-\x1F]/g.test(version)) { if (/[<>:"|?*\x00-\x1F]/g.test(version)) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0`, `${pluginIdLogPrefix}: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0.`,
); );
} }
if (/^\.\.?$/.test(version)) { if (/^\.\.?$/.test(version)) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}Invalid version tag specified! Do not name your version "." or "..". Try something like: 1.0.0`, `${pluginIdLogPrefix}: invalid version tag specified! Do not name your version "." or "..". Try something like: 1.0.0.`,
); );
} }
@ -137,7 +137,7 @@ export function cliDocsVersionCommand(
// Check if version already exists. // Check if version already exists.
if (versions.includes(version)) { if (versions.includes(version)) {
throw new Error( throw new Error(
`${pluginIdLogPrefix}This version already exists!. Use a version tag that does not already exist.`, `${pluginIdLogPrefix}: this version already exists! Use a version tag that does not already exist.`,
); );
} }
@ -151,7 +151,7 @@ export function cliDocsVersionCommand(
const newVersionDir = path.join(versionedDir, `version-${version}`); const newVersionDir = path.join(versionedDir, `version-${version}`);
fs.copySync(docsDir, newVersionDir); fs.copySync(docsDir, newVersionDir);
} else { } else {
throw new Error(`${pluginIdLogPrefix}There is no docs to version !`); throw new Error(`${pluginIdLogPrefix}: there is no docs to version!`);
} }
createVersionedSidebarFile({ createVersionedSidebarFile({
@ -166,5 +166,5 @@ export function cliDocsVersionCommand(
fs.ensureDirSync(path.dirname(versionsJSONFile)); fs.ensureDirSync(path.dirname(versionsJSONFile));
fs.writeFileSync(versionsJSONFile, `${JSON.stringify(versions, null, 2)}\n`); fs.writeFileSync(versionsJSONFile, `${JSON.stringify(versions, null, 2)}\n`);
console.log(`${pluginIdLogPrefix}Version ${version} created!`); console.log(`${pluginIdLogPrefix}: version ${version} created!`);
} }

View file

@ -35,12 +35,12 @@ describe('docsClientUtils', () => {
expect(() => expect(() =>
getActivePlugin(data, '/', {failfast: true}), getActivePlugin(data, '/', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`, `"Can't find active docs plugin for \\"/\\" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
); );
expect(() => expect(() =>
getActivePlugin(data, '/xyz', {failfast: true}), getActivePlugin(data, '/xyz', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/xyz, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`, `"Can't find active docs plugin for \\"/xyz\\" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
); );
const activePluginIos: ActivePlugin = { const activePluginIos: ActivePlugin = {

View file

@ -57,7 +57,7 @@ export function getActivePlugin(
if (!activePlugin && options.failfast) { if (!activePlugin && options.failfast) {
throw new Error( throw new Error(
`Can't find active docs plugin for pathname=${pathname}, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values( `Can't find active docs plugin for "${pathname}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
allPluginDatas, allPluginDatas,
) )
.map((plugin) => plugin.path) .map((plugin) => plugin.path)

View file

@ -149,7 +149,7 @@ export function processDocMetadata({
const baseID: string = frontMatter.id ?? unprefixedFileName; const baseID: string = frontMatter.id ?? unprefixedFileName;
if (baseID.includes('/')) { if (baseID.includes('/')) {
throw new Error(`Document id [${baseID}] cannot include "/".`); throw new Error(`Document id "${baseID}" cannot include slash.`);
} }
// For autogenerated sidebars, sidebar position can come from filename number prefix or frontmatter // For autogenerated sidebars, sidebar position can come from filename number prefix or frontmatter

View file

@ -144,12 +144,12 @@ export default function pluginContentDocs(
const docFiles = await readVersionDocs(versionMetadata, options); const docFiles = await readVersionDocs(versionMetadata, options);
if (docFiles.length === 0) { if (docFiles.length === 0) {
throw new Error( throw new Error(
`Docs version ${ `Docs version "${
versionMetadata.versionName versionMetadata.versionName
} has no docs! At least one doc should exist at path=[${path.relative( }" has no docs! At least one doc should exist at "${path.relative(
siteDir, siteDir,
versionMetadata.contentPath, versionMetadata.contentPath,
)}]`, )}".`,
); );
} }
async function processVersionDoc(docFile: DocFile) { async function processVersionDoc(docFile: DocFile) {

View file

@ -17,7 +17,7 @@ function getVersion(filePath: string, options: DocsMarkdownOption) {
); );
if (!versionFound) { if (!versionFound) {
throw new Error( throw new Error(
`Unexpected, markdown file does not belong to any docs version! file=${filePath}`, `Unexpected error: Markdown file at "${filePath}" does not belong to any docs version!`,
); );
} }
return versionFound; return versionFound;

View file

@ -130,9 +130,9 @@ export function validateOptions({
if (typeof options.excludeNextVersionDocs !== 'undefined') { if (typeof options.excludeNextVersionDocs !== 'undefined') {
console.log( console.log(
chalk.red( chalk.red(
`The docs plugin option excludeNextVersionDocs=${ `The docs plugin option "excludeNextVersionDocs=${
options.excludeNextVersionDocs options.excludeNextVersionDocs
} is deprecated. Use the includeCurrentVersion=${!options.excludeNextVersionDocs} option instead!"`, }" is deprecated. Use the "includeCurrentVersion=${!options.excludeNextVersionDocs}" option instead!"`,
), ),
); );
options.includeCurrentVersion = !options.excludeNextVersionDocs; options.includeCurrentVersion = !options.excludeNextVersionDocs;

View file

@ -27,8 +27,8 @@ export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
if (!docMetadata) { if (!docMetadata) {
throw new Error( throw new Error(
`Bad sidebars file. The document id '${docId}' was used in the sidebar, but no document with this id could be found. `Invalid sidebars file. The document with id "${docId}" was used in the sidebar, but no document with this id could be found.
Available document ids= Available document ids are:
- ${Object.keys(docsById).sort().join('\n- ')}`, - ${Object.keys(docsById).sort().join('\n- ')}`,
); );
} }

View file

@ -74,7 +74,7 @@ async function readCategoryMetadatasFile(
} catch (e) { } catch (e) {
console.error( console.error(
chalk.red( chalk.red(
`The docs sidebar category metadata file looks invalid!\nPath=${filePath}`, `The docs sidebar category metadata file looks invalid!\nPath: ${filePath}`,
), ),
); );
throw e; throw e;
@ -139,7 +139,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async functio
): string { ): string {
if (!isInAutogeneratedDir(doc)) { if (!isInAutogeneratedDir(doc)) {
throw new Error( throw new Error(
'getDocDirRelativeToAutogenDir() can only be called for subdocs of the sidebar autogen dir', 'getDocDirRelativeToAutogenDir() can only be called for subdocs of the sidebar autogen dir.',
); );
} }
// Is there a node API to compare 2 relative paths more easily? // Is there a node API to compare 2 relative paths more easily?
@ -160,7 +160,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async functio
if (docs.length === 0) { if (docs.length === 0) {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
`No docs found in dir ${item.dirName}: can't auto-generate a sidebar`, `No docs found in dir ${item.dirName}: can't auto-generate a sidebar.`,
), ),
); );
} }

View file

@ -118,18 +118,18 @@ function assertIsCategory(
assertItem(item, ['items', 'label', 'collapsed', 'customProps']); assertItem(item, ['items', 'label', 'collapsed', 'customProps']);
if (typeof item.label !== 'string') { if (typeof item.label !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "label" must be a string.`, `Error loading ${JSON.stringify(item)}: "label" must be a string.`,
); );
} }
if (!Array.isArray(item.items)) { if (!Array.isArray(item.items)) {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "items" must be an array.`, `Error loading ${JSON.stringify(item)}: "items" must be an array.`,
); );
} }
// "collapsed" is an optional property // "collapsed" is an optional property
if (item.hasOwnProperty('collapsed') && typeof item.collapsed !== 'boolean') { if (item.hasOwnProperty('collapsed') && typeof item.collapsed !== 'boolean') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "collapsed" must be a boolean.`, `Error loading ${JSON.stringify(item)}: "collapsed" must be a boolean.`,
); );
} }
} }
@ -140,14 +140,14 @@ function assertIsAutogenerated(
assertItem(item, ['dirName', 'customProps']); assertItem(item, ['dirName', 'customProps']);
if (typeof item.dirName !== 'string') { if (typeof item.dirName !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "dirName" must be a string.`, `Error loading ${JSON.stringify(item)}: "dirName" must be a string.`,
); );
} }
if (item.dirName.startsWith('/') || item.dirName.endsWith('/')) { if (item.dirName.startsWith('/') || item.dirName.endsWith('/')) {
throw new Error( throw new Error(
`Error loading ${JSON.stringify( `Error loading ${JSON.stringify(
item, item,
)}. "dirName" must be a dir path relative to the docs folder root, and should not start or end with /`, )}: "dirName" must be a dir path relative to the docs folder root, and should not start or end with slash`,
); );
} }
} }
@ -158,13 +158,13 @@ function assertIsDoc(
assertItem(item, ['id', 'label', 'customProps']); assertItem(item, ['id', 'label', 'customProps']);
if (typeof item.id !== 'string') { if (typeof item.id !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "id" must be a string.`, `Error loading ${JSON.stringify(item)}: "id" must be a string.`,
); );
} }
if (item.label && typeof item.label !== 'string') { if (item.label && typeof item.label !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "label" must be a string.`, `Error loading ${JSON.stringify(item)}: "label" must be a string.`,
); );
} }
} }
@ -175,12 +175,12 @@ function assertIsLink(
assertItem(item, ['href', 'label', 'customProps']); assertItem(item, ['href', 'label', 'customProps']);
if (typeof item.href !== 'string') { if (typeof item.href !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "href" must be a string.`, `Error loading ${JSON.stringify(item)}: "href" must be a string.`,
); );
} }
if (typeof item.label !== 'string') { if (typeof item.label !== 'string') {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(item)}. "label" must be a string.`, `Error loading ${JSON.stringify(item)}: "label" must be a string.`,
); );
} }
} }
@ -224,12 +224,12 @@ function normalizeItem(item: SidebarItemJSON): UnprocessedSidebarItem[] {
default: { default: {
const extraMigrationError = const extraMigrationError =
item.type === 'subcategory' item.type === 'subcategory'
? "Docusaurus v2: 'subcategory' has been renamed as 'category'" ? 'Docusaurus v2: "subcategory" has been renamed as "category".'
: ''; : '';
throw new Error( throw new Error(
`Unknown sidebar item type [${ `Unknown sidebar item type "${
item.type item.type
}]. Sidebar item=${JSON.stringify(item)} ${extraMigrationError}`, }". Sidebar item is ${JSON.stringify(item)}.\n${extraMigrationError}`,
); );
} }
} }
@ -485,11 +485,13 @@ export function createSidebarsUtils(sidebars: Sidebars) {
const invalidSidebarDocIds = difference(allSidebarDocIds, validDocIds); const invalidSidebarDocIds = difference(allSidebarDocIds, validDocIds);
if (invalidSidebarDocIds.length > 0) { if (invalidSidebarDocIds.length > 0) {
throw new Error( throw new Error(
`Bad sidebar file at '${toMessageRelativeFilePath(sidebarFilePath)}'. `Invalid sidebar file at "${toMessageRelativeFilePath(
sidebarFilePath,
)}".
These sidebar document ids do not exist: These sidebar document ids do not exist:
- ${invalidSidebarDocIds.sort().join('\n- ')}, - ${invalidSidebarDocIds.sort().join('\n- ')}
Available document ids= Available document ids are:
- ${validDocIds.sort().join('\n- ')}`, - ${validDocIds.sort().join('\n- ')}`,
); );
} }

View file

@ -47,8 +47,8 @@ export default function getSlug({
if (!isValidPathname(slug)) { if (!isValidPathname(slug)) {
throw new Error( throw new Error(
`We couldn't compute a valid slug for document with id=${baseID} in folder=${dirName} `We couldn't compute a valid slug for document with id "${baseID}" in "${dirName}" directory.
The slug we computed looks invalid: ${slug} The slug we computed looks invalid: ${slug}.
Maybe your slug frontmatter is incorrect or you use weird chars in the file path? Maybe your slug frontmatter is incorrect or you use weird chars in the file path?
By using the slug frontmatter, you should be able to fix this error, by using the slug of your choice: By using the slug frontmatter, you should be able to fix this error, by using the slug of your choice:

View file

@ -59,12 +59,12 @@ export function getVersionsFilePath(siteDir: string, pluginId: string): string {
function ensureValidVersionString(version: unknown): asserts version is string { function ensureValidVersionString(version: unknown): asserts version is string {
if (typeof version !== 'string') { if (typeof version !== 'string') {
throw new Error( throw new Error(
`versions should be strings. Found type=[${typeof version}] for version=[${version}]`, `Versions should be strings. Found type "${typeof version}" for version "${version}".`,
); );
} }
// Should we forbid versions with special chars like / ? // Should we forbid versions with special chars like / ?
if (version.trim().length === 0) { if (version.trim().length === 0) {
throw new Error(`Invalid version=[${version}]`); throw new Error(`Invalid version "${version}".`);
} }
} }
@ -73,7 +73,7 @@ function ensureValidVersionArray(
): asserts versionArray is string[] { ): asserts versionArray is string[] {
if (!(versionArray instanceof Array)) { if (!(versionArray instanceof Array)) {
throw new Error( throw new Error(
`The versions file should contain an array of versions! Found content=${JSON.stringify( `The versions file should contain an array of versions! Found content: ${JSON.stringify(
versionArray, versionArray,
)}`, )}`,
); );
@ -106,7 +106,7 @@ function readVersionNames(
if (!versionFileContent && options.disableVersioning) { if (!versionFileContent && options.disableVersioning) {
throw new Error( throw new Error(
`Docs: using disableVersioning=${options.disableVersioning} option on a non-versioned site does not make sense`, `Docs: using "disableVersioning=${options.disableVersioning}" option on a non-versioned site does not make sense.`,
); );
} }
@ -124,7 +124,7 @@ function readVersionNames(
if (versions.length === 0) { if (versions.length === 0) {
throw new Error( throw new Error(
`It is not possible to use docs without any version. Please check the configuration of these options: includeCurrentVersion=${options.includeCurrentVersion} disableVersioning=${options.disableVersioning}`, `It is not possible to use docs without any version. Please check the configuration of these options: "includeCurrentVersion=${options.includeCurrentVersion}", "disableVersioning=${options.disableVersioning}".`,
); );
} }
@ -342,10 +342,10 @@ function checkVersionMetadataPaths({
if (!fs.existsSync(contentPath)) { if (!fs.existsSync(contentPath)) {
throw new Error( throw new Error(
`The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${path.relative( `The docs folder does not exist for version "${versionName}". A docs folder is expected to be found at ${path.relative(
siteDir, siteDir,
contentPath, contentPath,
)}`, )}.`,
); );
} }
@ -358,11 +358,11 @@ function checkVersionMetadataPaths({
typeof sidebarFilePath === 'string' && typeof sidebarFilePath === 'string' &&
!fs.existsSync(sidebarFilePath) !fs.existsSync(sidebarFilePath)
) { ) {
throw new Error(`The path to the sidebar file does not exist at [${path.relative( throw new Error(`The path to the sidebar file does not exist at "${path.relative(
siteDir, siteDir,
sidebarFilePath, sidebarFilePath,
)}]. )}".
Please set the docs [sidebarPath] field in your config file to: Please set the docs "sidebarPath" field in your config file to:
- a sidebars path that exists - a sidebars path that exists
- false: to disable the sidebar - false: to disable the sidebar
- undefined: for Docusaurus generates it automatically`); - undefined: for Docusaurus generates it automatically`);
@ -403,16 +403,16 @@ function checkVersionsOptions(
); );
if (unknownVersionConfigNames.length > 0) { if (unknownVersionConfigNames.length > 0) {
throw new Error( throw new Error(
`Bad docs options.versions: unknown versions found: ${unknownVersionConfigNames.join( `Invalid docs option "versions": unknown versions (${unknownVersionConfigNames.join(
',', ',',
)}. ${availableVersionNamesMsg}`, )}) found. ${availableVersionNamesMsg}`,
); );
} }
if (options.onlyIncludeVersions) { if (options.onlyIncludeVersions) {
if (options.onlyIncludeVersions.length === 0) { if (options.onlyIncludeVersions.length === 0) {
throw new Error( throw new Error(
`Bad docs options.onlyIncludeVersions: an empty array is not allowed, at least one version is needed`, `Invalid docs option "onlyIncludeVersions": an empty array is not allowed, at least one version is needed.`,
); );
} }
const unknownOnlyIncludeVersionNames = difference( const unknownOnlyIncludeVersionNames = difference(
@ -421,9 +421,9 @@ function checkVersionsOptions(
); );
if (unknownOnlyIncludeVersionNames.length > 0) { if (unknownOnlyIncludeVersionNames.length > 0) {
throw new Error( throw new Error(
`Bad docs options.onlyIncludeVersions: unknown versions found: ${unknownOnlyIncludeVersionNames.join( `Invalid docs option "onlyIncludeVersions": unknown versions (${unknownOnlyIncludeVersionNames.join(
',', ',',
)}. ${availableVersionNamesMsg}`, )}) found. ${availableVersionNamesMsg}`,
); );
} }
if ( if (
@ -431,7 +431,7 @@ function checkVersionsOptions(
!options.onlyIncludeVersions.includes(options.lastVersion) !options.onlyIncludeVersions.includes(options.lastVersion)
) { ) {
throw new Error( throw new Error(
`Bad docs options.lastVersion: if you use both the onlyIncludeVersions and lastVersion options, then lastVersion must be present in the provided onlyIncludeVersions array`, `Invalid docs option "lastVersion": if you use both the "onlyIncludeVersions" and "lastVersion" options, then "lastVersion" must be present in the provided "onlyIncludeVersions" array.`,
); );
} }
} }

View file

@ -14,7 +14,7 @@ module.exports = function (context) {
if (!googleAnalytics) { if (!googleAnalytics) {
throw new Error( throw new Error(
`You need to specify 'googleAnalytics' object in 'themeConfig' with 'trackingId' field in it to use docusaurus-plugin-google-analytics`, `You need to specify "googleAnalytics" object in "themeConfig" with "trackingId" field in it to use docusaurus-plugin-google-analytics.`,
); );
} }
@ -22,7 +22,7 @@ module.exports = function (context) {
if (!trackingID) { if (!trackingID) {
throw new Error( throw new Error(
'You specified the `googleAnalytics` object in `themeConfig` but the `trackingID` field was missing. ' + 'You specified the "googleAnalytics" object in "themeConfig" but the "trackingID" field was missing. ' +
'Please ensure this is not a mistake.', 'Please ensure this is not a mistake.',
); );
} }

View file

@ -14,7 +14,7 @@ module.exports = function (context) {
if (!gtag) { if (!gtag) {
throw new Error( throw new Error(
`You need to specify 'gtag' object in 'themeConfig' with 'trackingId' field in it to use docusaurus-plugin-google-gtag`, `You need to specify "gtag" object in "themeConfig" with "trackingId" field in it to use docusaurus-plugin-google-gtag.`,
); );
} }
@ -22,7 +22,7 @@ module.exports = function (context) {
if (!trackingID) { if (!trackingID) {
throw new Error( throw new Error(
'You specified the `gtag` object in `themeConfig` but the `trackingID` field was missing. ' + 'You specified the "gtag" object in "themeConfig" but the "trackingID" field was missing. ' +
'Please ensure this is not a mistake.', 'Please ensure this is not a mistake.',
); );
} }

View file

@ -29,7 +29,9 @@ describe('createSitemap', () => {
test('empty site', () => { test('empty site', () => {
return expect(async () => { return expect(async () => {
await createSitemap({} as DocusaurusConfig, [], {}); await createSitemap({} as DocusaurusConfig, [], {});
}).rejects.toThrow('url in docusaurus.config.js cannot be empty/undefined'); }).rejects.toThrow(
'URL in docusaurus.config.js cannot be empty/undefined.',
);
}); });
test('exclusion of 404 page', async () => { test('exclusion of 404 page', async () => {

View file

@ -18,7 +18,7 @@ export default async function createSitemap(
): Promise<string> { ): Promise<string> {
const {url: hostname} = siteConfig; const {url: hostname} = siteConfig;
if (!hostname) { if (!hostname) {
throw new Error('url in docusaurus.config.js cannot be empty/undefined'); throw new Error('URL in docusaurus.config.js cannot be empty/undefined.');
} }
const {changefreq, priority, trailingSlash} = options; const {changefreq, priority, trailingSlash} = options;

View file

@ -38,7 +38,7 @@ export default function pluginSitemap(
try { try {
await fs.outputFile(sitemapPath, generatedSitemap); await fs.outputFile(sitemapPath, generatedSitemap);
} catch (err) { } catch (err) {
throw new Error(`Sitemap error: ${err}`); throw new Error(`Writing sitemap failed: ${err}`);
} }
}, },
}; };

View file

@ -29,8 +29,8 @@ export default function DocNavbarItem({
if (!doc) { if (!doc) {
const docIds = version.docs.map((versionDoc) => versionDoc.id).join('\n- '); const docIds = version.docs.map((versionDoc) => versionDoc.id).join('\n- ');
throw new Error( throw new Error(
`DocNavbarItem: couldn't find any doc with id=${docId} in version ${version.name}. `DocNavbarItem: couldn't find any doc with "${docId}" id in version "${version.name}".
Available docIds=\n- ${docIds}`, Available doc ids:\n- ${docIds}`,
); );
} }

View file

@ -34,7 +34,7 @@ const getNavbarItemComponent = (
) => { ) => {
const navbarItemComponent = NavbarItemComponents[type]; const navbarItemComponent = NavbarItemComponents[type];
if (!navbarItemComponent) { if (!navbarItemComponent) {
throw new Error(`No NavbarItem component found for type=${type}.`); throw new Error(`No NavbarItem component found for type "${type}".`);
} }
return navbarItemComponent(); return navbarItemComponent();
}; };

View file

@ -14,7 +14,7 @@ function useThemeContext(): ThemeContextProps {
const context = useContext<ThemeContextProps | undefined>(ThemeContext); const context = useContext<ThemeContextProps | undefined>(ThemeContext);
if (context == null) { if (context == null) {
throw new Error( throw new Error(
'`useThemeContext` is used outside of `Layout` Component. See https://docusaurus.io/docs/api/themes/configuration#usethemecontext.', '"useThemeContext" is used outside of "Layout" component. Please see https://docusaurus.io/docs/api/themes/configuration#usethemecontext.',
); );
} }
return context; return context;

View file

@ -16,7 +16,7 @@ function useUserPreferencesContext(): UserPreferencesContextProps {
); );
if (context == null) { if (context == null) {
throw new Error( throw new Error(
'`useUserPreferencesContext` is used outside of `Layout` Component.', '"useUserPreferencesContext" is used outside of "Layout" component.',
); );
} }
return context; return context;

View file

@ -158,7 +158,7 @@ export function useDocsPreferredVersionContext(): DocsPreferredVersionContextVal
const value = useContext(Context); const value = useContext(Context);
if (!value) { if (!value) {
throw new Error( throw new Error(
"Can't find docs preferred context, maybe you forgot to use the DocsPreferredVersionContextProvider ?", 'Can\'t find docs preferred context, maybe you forgot to use the "DocsPreferredVersionContextProvider"?',
); );
} }
return value; return value;

View file

@ -18,7 +18,7 @@ function getBrowserStorage(
): Storage | null { ): Storage | null {
if (typeof window === 'undefined') { if (typeof window === 'undefined') {
throw new Error( throw new Error(
'Browser storage is not available on NodeJS / Docusaurus SSR process', 'Browser storage is not available on Node.js/Docusaurus SSR process.',
); );
} }
if (storageType === 'none') { if (storageType === 'none') {
@ -42,7 +42,7 @@ function logOnceBrowserStorageNotAvailableWarning(error: Error) {
if (!hasLoggedBrowserStorageNotAvailableWarning) { if (!hasLoggedBrowserStorageNotAvailableWarning) {
console.warn( console.warn(
`Docusaurus browser storage is not available. `Docusaurus browser storage is not available.
Possible reasons: running Docusaurus in an Iframe, in an Incognito browser session, or using too strict browser privacy settings.`, Possible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.`,
error, error,
); );
hasLoggedBrowserStorageNotAvailableWarning = true; hasLoggedBrowserStorageNotAvailableWarning = true;
@ -65,7 +65,7 @@ const NoopStorageSlot: StorageSlot = {
// Fail-fast, as storage APIs should not be used during the SSR process // Fail-fast, as storage APIs should not be used during the SSR process
function createServerStorageSlot(key: string): StorageSlot { function createServerStorageSlot(key: string): StorageSlot {
function throwError(): never { function throwError(): never {
throw new Error(`Illegal storage API usage for storage key=${key}. throw new Error(`Illegal storage API usage for storage key "${key}".
Docusaurus storage APIs are not supposed to be called on the server-rendering process. Docusaurus storage APIs are not supposed to be called on the server-rendering process.
Please only call storage APIs in effects and event handlers.`); Please only call storage APIs in effects and event handlers.`);
} }

View file

@ -70,7 +70,7 @@ function useLocalePluralForms(): LocalePluralForms {
try { try {
return createLocalePluralForms(currentLocale); return createLocalePluralForms(currentLocale);
} catch (e) { } catch (e) {
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.
`); `);
return EnglishPluralForms; return EnglishPluralForms;

View file

@ -31,7 +31,7 @@ describe('validateFrontMatter', () => {
validateFrontMatter(frontMatter, schema), validateFrontMatter(frontMatter, schema),
).toThrowErrorMatchingInlineSnapshot(`"\\"test\\" must be a string"`); ).toThrowErrorMatchingInlineSnapshot(`"\\"test\\" must be a string"`);
expect(consoleError).toHaveBeenCalledWith( expect(consoleError).toHaveBeenCalledWith(
expect.stringContaining('The following FrontMatter'), expect.stringContaining('The following frontmatter'),
); );
}); });

View file

@ -50,5 +50,5 @@ export const PathnameSchema = Joi.string()
} }
}) })
.message( .message(
'{{#label}} is not a valid pathname. Pathname should start with / and not contain any domain or query string', '{{#label}} is not a valid pathname. Pathname should start with slash and not contain any domain or query string.',
); );

View file

@ -20,14 +20,14 @@ export const isValidationDisabledEscapeHatch =
if (isValidationDisabledEscapeHatch) { if (isValidationDisabledEscapeHatch) {
console.error( console.error(
chalk.red( chalk.red(
'You should avoid using DISABLE_DOCUSAURUS_VALIDATION escape hatch, this will be removed', 'You should avoid using DISABLE_DOCUSAURUS_VALIDATION escape hatch, this will be removed.',
), ),
); );
} }
export const logValidationBugReportHint = (): void => { export const logValidationBugReportHint = (): void => {
console.log( console.log(
`\n${chalk.red('A validation error occured.')}${chalk.cyanBright( `\n${chalk.red('A validation error occurred.')}${chalk.cyanBright(
'\nThe validation system was added recently to Docusaurus as an attempt to avoid user configuration errors.' + '\nThe validation system was added recently to Docusaurus as an attempt to avoid user configuration errors.' +
'\nWe may have made some mistakes.' + '\nWe may have made some mistakes.' +
'\nIf you think your configuration is valid and should keep working, please open a bug report.', '\nIf you think your configuration is valid and should keep working, please open a bug report.',
@ -141,7 +141,7 @@ export function validateFrontMatter<T>(
console.error( console.error(
chalk.red( chalk.red(
`The following FrontMatter:\n${chalk.yellow( `The following frontmatter:\n${chalk.yellow(
frontMatterString, frontMatterString,
)}\ncontains invalid values for field(s): ${invalidFields}.\n${errorMessages}\n`, )}\ncontains invalid values for field(s): ${invalidFields}.\n${errorMessages}\n`,
), ),

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`getFolderContainingFile throw if no folder contain such file 1`] = ` exports[`getFolderContainingFile throw if no folder contain such file 1`] = `
"relativeFilePath=[index.test.ts] does not exist in any of these folders: "File \\"index.test.ts\\" does not exist in any of these folders:
- /abcdef - /abcdef
- /gehij - /gehij
- /klmn]" - /klmn]"

View file

@ -441,12 +441,12 @@ describe('getElementsAround', () => {
expect(() => expect(() =>
getElementsAround(['a', 'b', 'c', 'd'], -1), getElementsAround(['a', 'b', 'c', 'd'], -1),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Valid aroundIndex for array (of size 4) are between 0 and 3, but you provided aroundIndex=-1"`, `"Valid \\"aroundIndex\\" for array (of size 4) are between 0 and 3, but you provided -1."`,
); );
expect(() => expect(() =>
getElementsAround(['a', 'b', 'c', 'd'], 4), getElementsAround(['a', 'b', 'c', 'd'], 4),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Valid aroundIndex for array (of size 4) are between 0 and 3, but you provided aroundIndex=4"`, `"Valid \\"aroundIndex\\" for array (of size 4) are between 0 and 3, but you provided 4."`,
); );
}); });
}); });

View file

@ -342,7 +342,7 @@ export function getElementsAround<T extends unknown>(
const max = array.length - 1; const max = array.length - 1;
if (aroundIndex < min || aroundIndex > max) { if (aroundIndex < min || aroundIndex > max) {
throw new Error( throw new Error(
`Valid aroundIndex for array (of size ${array.length}) are between ${min} and ${max}, but you provided aroundIndex=${aroundIndex}`, `Valid "aroundIndex" for array (of size ${array.length}) are between ${min} and ${max}, but you provided ${aroundIndex}.`,
); );
} }
const previous = aroundIndex === min ? undefined : array[aroundIndex - 1]; const previous = aroundIndex === min ? undefined : array[aroundIndex - 1];
@ -427,7 +427,7 @@ export async function getFolderContainingFile(
// should never happen, as the source was read from the FS anyway... // should never happen, as the source was read from the FS anyway...
if (!maybeFolderPath) { if (!maybeFolderPath) {
throw new Error( throw new Error(
`relativeFilePath=[${relativeFilePath}] does not exist in any of these folders: \n- ${folderPaths.join( `File "${relativeFilePath}" does not exist in any of these folders:\n- ${folderPaths.join(
'\n- ', '\n- ',
)}]`, )}]`,
); );
@ -455,7 +455,7 @@ export function reportMessage(
throw new Error(message); throw new Error(message);
default: default:
throw new Error( throw new Error(
`unexpected reportingSeverity value: ${reportingSeverity}`, `Unexpected "reportingSeverity" value: ${reportingSeverity}.`,
); );
} }
} }

View file

@ -160,8 +160,8 @@ export function parseMarkdownString(
}; };
} catch (e) { } catch (e) {
console.error( console.error(
chalk.red(`Error while parsing markdown front matter. chalk.red(`Error while parsing Markdown frontmatter.
This can happen if you use special characters like : in frontmatter values (try using "" around that value)`), This can happen if you use special characters in frontmatter values (try using double quotes around that value).`),
); );
throw e; throw e;
} }
@ -176,8 +176,7 @@ export async function parseMarkdownFile(
return parseMarkdownString(markdownString, options); return parseMarkdownString(markdownString, options);
} catch (e) { } catch (e) {
throw new Error( throw new Error(
`Error while parsing markdown file ${source} `Error while parsing Markdown file ${source}: "${e.message}".`,
${e.message}`,
); );
} }
} }

View file

@ -83,9 +83,9 @@ if (notifier.update && semver.gt(this.update.latest, this.update.current)) {
// notify user if node version needs to be updated // notify user if node version needs to be updated
if (!semver.satisfies(process.version, requiredVersion)) { if (!semver.satisfies(process.version, requiredVersion)) {
console.log( console.log(
chalk.red(`\nMinimum Node version not met :(`) + chalk.red(`\nMinimum Node.js version not met :(`) +
chalk.yellow( chalk.yellow(
`\n\nYou are using Node ${process.version}. We require Node ${requiredVersion} or up!\n`, `\n\nYou are using Node.js ${process.version}. We require Node.js ${requiredVersion} or up!\n`,
), ),
); );
process.exit(1); process.exit(1);
@ -95,26 +95,26 @@ cli.version(require('../package.json').version).usage('<command> [options]');
cli cli
.command('build [siteDir]') .command('build [siteDir]')
.description('Build website') .description('Build website.')
.option( .option(
'--bundle-analyzer', '--bundle-analyzer',
'Visualize size of webpack output files with an interactive zoomable treemap (default: false)', 'visualize size of webpack output files with an interactive zoomable treemap (default: false)',
) )
.option( .option(
'--out-dir <dir>', '--out-dir <dir>',
'The full path for the new output directory, relative to the current workspace (default: build).', 'the full path for the new output directory, relative to the current workspace (default: build)',
) )
.option( .option(
'--config <config>', '--config <config>',
'Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js`', 'path to docusaurus config file (default: `[siteDir]/docusaurus.config.js`)',
) )
.option( .option(
'-l, --locale <locale>', '-l, --locale <locale>',
'Build the site in a specified locale. Build all known locales otherwise.', 'build the site in a specified locale. Build all known locales otherwise',
) )
.option( .option(
'--no-minify', '--no-minify',
'Build website without minimizing JS bundles (default: false)', 'build website without minimizing JS bundles (default: false)',
) )
.action((siteDir = '.', {bundleAnalyzer, config, outDir, locale, minify}) => { .action((siteDir = '.', {bundleAnalyzer, config, outDir, locale, minify}) => {
build(path.resolve(siteDir), { build(path.resolve(siteDir), {
@ -131,9 +131,9 @@ cli
.description('Copy the theme files into website folder for customization.') .description('Copy the theme files into website folder for customization.')
.option( .option(
'--typescript', '--typescript',
'Copy TypeScript theme files when possible (default: false)', 'copy TypeScript theme files when possible (default: false)',
) )
.option('--danger', 'Enable swizzle for internal component of themes') .option('--danger', 'enable swizzle for internal component of themes')
.action((themeName, componentName, siteDir = '.', {typescript, danger}) => { .action((themeName, componentName, siteDir = '.', {typescript, danger}) => {
swizzle( swizzle(
path.resolve(siteDir), path.resolve(siteDir),
@ -146,22 +146,22 @@ cli
cli cli
.command('deploy [siteDir]') .command('deploy [siteDir]')
.description('Deploy website to GitHub pages') .description('Deploy website to GitHub pages.')
.option( .option(
'-l, --locale <locale>', '-l, --locale <locale>',
'Deploy the site in a specified locale. Deploy all known locales otherwise.', 'deploy the site in a specified locale. Deploy all known locales otherwise',
) )
.option( .option(
'--out-dir <dir>', '--out-dir <dir>',
'The full path for the new output directory, relative to the current workspace (default: build).', 'the full path for the new output directory, relative to the current workspace (default: build)',
) )
.option( .option(
'--config <config>', '--config <config>',
'Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js`', 'path to Docusaurus config file (default: `[siteDir]/docusaurus.config.js`)',
) )
.option( .option(
'--skip-build', '--skip-build',
'Skip building website before deploy it (default: false)', 'skip building website before deploy it (default: false)',
) )
.action((siteDir = '.', {outDir, skipBuild, config}) => { .action((siteDir = '.', {outDir, skipBuild, config}) => {
deploy(path.resolve(siteDir), { deploy(path.resolve(siteDir), {
@ -173,22 +173,22 @@ cli
cli cli
.command('start [siteDir]') .command('start [siteDir]')
.description('Start the development server') .description('Start the development server.')
.option('-p, --port <port>', 'use specified port (default: 3000)') .option('-p, --port <port>', 'use specified port (default: 3000)')
.option('-h, --host <host>', 'use specified host (default: localhost') .option('-h, --host <host>', 'use specified host (default: localhost)')
.option('-l, --locale <locale>', 'use specified site locale') .option('-l, --locale <locale>', 'use specified site locale')
.option( .option(
'--hot-only', '--hot-only',
'Do not fallback to page refresh if hot reload fails (default: false)', 'do not fallback to page refresh if hot reload fails (default: false)',
) )
.option( .option(
'--config <config>', '--config <config>',
'Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js`', 'path to Docusaurus config file (default: `[siteDir]/docusaurus.config.js`)',
) )
.option('--no-open', 'Do not open page in the browser (default: false)') .option('--no-open', 'do not open page in the browser (default: false)')
.option( .option(
'--poll [interval]', '--poll [interval]',
'Use polling rather than watching for reload (default: false). Can specify a poll interval in milliseconds.', 'use polling rather than watching for reload (default: false). Can specify a poll interval in milliseconds',
) )
.action( .action(
(siteDir = '.', {port, host, locale, config, hotOnly, open, poll}) => { (siteDir = '.', {port, host, locale, config, hotOnly, open, poll}) => {
@ -206,18 +206,18 @@ cli
cli cli
.command('serve [siteDir]') .command('serve [siteDir]')
.description('Serve website') .description('Serve website locally.')
.option( .option(
'--dir <dir>', '--dir <dir>',
'The full path for the new output directory, relative to the current workspace (default: build).', 'the full path for the new output directory, relative to the current workspace (default: build)',
) )
.option( .option(
'--config <config>', '--config <config>',
'Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js`', 'path to Docusaurus config file (default: `[siteDir]/docusaurus.config.js`)',
) )
.option('-p, --port <port>', 'use specified port (default: 3000)') .option('-p, --port <port>', 'use specified port (default: 3000)')
.option('--build', 'Build website before serving (default: false)') .option('--build', 'build website before serving (default: false)')
.option('-h, --host <host>', 'use specified host (default: localhost') .option('-h, --host <host>', 'use specified host (default: localhost)')
.action( .action(
( (
siteDir = '.', siteDir = '.',
@ -241,29 +241,29 @@ cli
cli cli
.command('clear [siteDir]') .command('clear [siteDir]')
.description('Remove build artifacts') .description('Remove build artifacts.')
.action((siteDir = '.') => { .action((siteDir = '.') => {
clear(path.resolve(siteDir)); clear(path.resolve(siteDir));
}); });
cli cli
.command('write-translations [siteDir]') .command('write-translations [siteDir]')
.description('Extract required translations of your site') .description('Extract required translations of your site.')
.option( .option(
'-l, --locale <locale>', '-l, --locale <locale>',
'The locale folder to write the translations\n"--locale fr" will write translations in ./i18n/fr folder)', 'the locale folder to write the translations\n"--locale fr" will write translations in ./i18n/fr folder)',
) )
.option( .option(
'--override', '--override',
'By default, we only append missing translation messages to existing translation files. This option allows to override existing translation messages. Make sure to commit or backup your existing translations, as they may be overridden.', 'by default, we only append missing translation messages to existing translation files. This option allows to override existing translation messages. Make sure to commit or backup your existing translations, as they may be overridden',
) )
.option( .option(
'--config <config>', '--config <config>',
'Path to docusaurus config file, default to `[siteDir]/docusaurus.config.js`', 'path to Docusaurus config file (default:`[siteDir]/docusaurus.config.js`)',
) )
.option( .option(
'--messagePrefix <messagePrefix>', '--messagePrefix <messagePrefix>',
'Allows to init new written messages with a given prefix. This might help you to highlight untranslated message to make them stand out in the UI.', 'allows to init new written messages with a given prefix. This might help you to highlight untranslated message to make them stand out in the UI',
) )
.action( .action(
( (
@ -281,14 +281,14 @@ cli
cli cli
.command('write-heading-ids [contentDir]') .command('write-heading-ids [contentDir]')
.description('Generate heading ids in Markdown content') .description('Generate heading ids in Markdown content.')
.action((siteDir = '.') => { .action((siteDir = '.') => {
writeHeadingIds(siteDir); writeHeadingIds(siteDir);
}); });
cli.arguments('<command>').action((cmd) => { cli.arguments('<command>').action((cmd) => {
cli.outputHelp(); cli.outputHelp();
console.log(` ${chalk.red(`\n Unknown command ${chalk.yellow(cmd)}.`)}`); console.log(` ${chalk.red(`\n Unknown command ${chalk.yellow(cmd)}.`)}.`);
console.log(); console.log();
}); });

View file

@ -127,7 +127,7 @@ export default async function choosePort(
(err) => { (err) => {
throw new Error( throw new Error(
`${chalk.red(`Could not find an open port at ${chalk.bold(host)}.`)}\n${ `${chalk.red(`Could not find an open port at ${chalk.bold(host)}.`)}\n${
`Network error message: ${err.message}` || err `Network error message: "${err.message}".` || err
}\n`, }\n`,
); );
}, },

View file

@ -13,7 +13,7 @@ function useDocusaurusContext(): DocusaurusContext {
const docusaurusContext = useContext(context); const docusaurusContext = useContext(context);
if (docusaurusContext === null) { if (docusaurusContext === null) {
// should not happen normally // should not happen normally
throw new Error('Docusaurus context not provided'); throw new Error('Docusaurus context not provided.');
} }
return docusaurusContext; return docusaurusContext;
} }

View file

@ -16,7 +16,7 @@ const DEFAULT_PLUGIN_ID = 'default';
export default function useGlobalData(): Record<string, unknown> { export default function useGlobalData(): Record<string, unknown> {
const {globalData} = useDocusaurusContext(); const {globalData} = useDocusaurusContext();
if (!globalData) { if (!globalData) {
throw new Error('Docusaurus global data not found'); throw new Error('Docusaurus global data not found.');
} }
return globalData; return globalData;
} }
@ -28,7 +28,7 @@ export function useAllPluginInstancesData<T = unknown>(
const pluginGlobalData = globalData[pluginName]; const pluginGlobalData = globalData[pluginName];
if (!pluginGlobalData) { if (!pluginGlobalData) {
throw new Error( throw new Error(
`Docusaurus plugin global data not found for pluginName=${pluginName}`, `Docusaurus plugin global data not found for "${pluginName}" plugin.`,
); );
} }
return pluginGlobalData as Record<string, T>; return pluginGlobalData as Record<string, T>;
@ -42,7 +42,7 @@ export function usePluginData<T = unknown>(
const pluginInstanceGlobalData = pluginGlobalData[pluginId]; const pluginInstanceGlobalData = pluginGlobalData[pluginId];
if (!pluginInstanceGlobalData) { if (!pluginInstanceGlobalData) {
throw new Error( throw new Error(
`Docusaurus plugin global data not found for pluginName=${pluginName} and pluginId=${pluginId}`, `Docusaurus plugin global data not found for "${pluginName}" plugin with id "${pluginId}".`,
); );
} }
return pluginInstanceGlobalData as T; return pluginInstanceGlobalData as T;

View file

@ -159,7 +159,7 @@ async function doRender(locals) {
) { ) {
console.error( console.error(
chalk.red( chalk.red(
'\nDocusaurus user: you probably have this known error due to using a monorepo/workspace.\nWe have a workaround for you, check https://github.com/facebook/docusaurus/issues/3515\n', '\nDocusaurus user: you probably have this known error due to using a monorepo/workspace.\nWe have a workaround for you, please see https://github.com/facebook/docusaurus/issues/3515\n',
), ),
); );
} }

View file

@ -16,7 +16,7 @@ describe('transformMarkdownHeadingLine', () => {
expect(() => expect(() =>
transformMarkdownHeadingLine('ABC', new GithubSlugger()), transformMarkdownHeadingLine('ABC', new GithubSlugger()),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Line is not a markdown heading: ABC"`, `"Line is not a Markdown heading: ABC."`,
); );
}); });

View file

@ -53,7 +53,7 @@ export default async function build(
isLastLocale, isLastLocale,
}); });
} catch (e) { } catch (e) {
console.error(`Unable to build website for locale ${locale}.`); console.error(`Unable to build website for locale "${locale}".`);
throw e; throw e;
} }
} }
@ -72,7 +72,7 @@ export default async function build(
if (i18n.locales.length > 1) { if (i18n.locales.length > 1) {
console.log( console.log(
chalk.yellow( chalk.yellow(
`\nSite will be built for all these locales: `\nWebsite will be built for all these locales:
- ${i18n.locales.join('\n- ')}`, - ${i18n.locales.join('\n- ')}`,
), ),
); );
@ -239,7 +239,7 @@ async function buildLocale({
}); });
console.log( console.log(
`${chalk.green(`Success!`)} Generated static files in ${chalk.cyan( `${chalk.green(`Success!`)} Generated static files in "${chalk.cyan(
path.relative(process.cwd(), outDir), path.relative(process.cwd(), outDir),
)}.`, )}.`,
); );
@ -248,7 +248,7 @@ async function buildLocale({
console.log( console.log(
`\nUse ${chalk.greenBright( `\nUse ${chalk.greenBright(
'`npm run serve`', '`npm run serve`',
)} to test your build locally.\n`, )} command to test your build locally.\n`,
); );
} }

View file

@ -13,10 +13,10 @@ function removePath(fsPath: string) {
return fs return fs
.remove(path.join(fsPath)) .remove(path.join(fsPath))
.then(() => { .then(() => {
console.log(`${chalk.green(`Removing ${fsPath}`)}`); console.log(chalk.green(`Successfully removed "${fsPath}" directory.`));
}) })
.catch((err) => { .catch((err) => {
console.error(`Could not remove ${fsPath}`); console.error(`Could not remove ${fsPath} directory.`);
console.error(err); console.error(err);
}); });
} }

View file

@ -28,7 +28,7 @@ function shellExecLog(cmd) {
const result = shell.exec(cmd); const result = shell.exec(cmd);
console.log( console.log(
`${chalk.cyan('CMD:')} ${obfuscateGitPass(cmd)} ${chalk.cyan( `${chalk.cyan('CMD:')} ${obfuscateGitPass(cmd)} ${chalk.cyan(
`(code=${result.code})`, `(code: ${result.code})`,
)}`, )}`,
); );
return result; return result;
@ -68,7 +68,7 @@ export default async function deploy(
siteConfig.organizationName; siteConfig.organizationName;
if (!organizationName) { if (!organizationName) {
throw new Error( throw new Error(
`Missing project organization name. Did you forget to define 'organizationName' in ${siteConfigPath}? You may also export it via the ORGANIZATION_NAME environment variable.`, `Missing project organization name. Did you forget to define "organizationName" in ${siteConfigPath}? You may also export it via the ORGANIZATION_NAME environment variable.`,
); );
} }
console.log(`${chalk.cyan('organizationName:')} ${organizationName}`); console.log(`${chalk.cyan('organizationName:')} ${organizationName}`);
@ -79,7 +79,7 @@ export default async function deploy(
siteConfig.projectName; siteConfig.projectName;
if (!projectName) { if (!projectName) {
throw new Error( throw new Error(
`Missing project name. Did you forget to define 'projectName' in ${siteConfigPath}? You may also export it via the PROJECT_NAME environment variable.`, `Missing project name. Did you forget to define "projectName" in ${siteConfigPath}? You may also export it via the PROJECT_NAME environment variable.`,
); );
} }
console.log(`${chalk.cyan('projectName:')} ${projectName}`); console.log(`${chalk.cyan('projectName:')} ${projectName}`);
@ -88,7 +88,7 @@ export default async function deploy(
const isPullRequest = const isPullRequest =
process.env.CI_PULL_REQUEST || process.env.CIRCLE_PULL_REQUEST; process.env.CI_PULL_REQUEST || process.env.CIRCLE_PULL_REQUEST;
if (isPullRequest) { if (isPullRequest) {
shell.echo('Skipping deploy on a pull request'); shell.echo('Skipping deploy on a pull request.');
shell.exit(0); shell.exit(0);
} }
@ -148,7 +148,7 @@ export default async function deploy(
path.join(os.tmpdir(), `${projectName}-${deploymentBranch}`), path.join(os.tmpdir(), `${projectName}-${deploymentBranch}`),
); );
if (shellExecLog(`git clone ${remoteBranch} ${toPath}`).code !== 0) { if (shellExecLog(`git clone ${remoteBranch} ${toPath}`).code !== 0) {
throw new Error(`Error: git clone failed in ${toPath}`); throw new Error(`Running "git clone" command in "${toPath}" failed.`);
} }
shell.cd(toPath); shell.cd(toPath);
@ -164,7 +164,9 @@ export default async function deploy(
if ( if (
shellExecLog(`git checkout --orphan ${deploymentBranch}`).code !== 0 shellExecLog(`git checkout --orphan ${deploymentBranch}`).code !== 0
) { ) {
throw new Error(`Error: Git checkout ${deploymentBranch} failed`); throw new Error(
`Running "git checkout ${deploymentBranch}" command failed.`,
);
} }
} else if ( } else if (
shellExecLog(`git checkout -b ${deploymentBranch}`).code + shellExecLog(`git checkout -b ${deploymentBranch}`).code +
@ -173,7 +175,9 @@ export default async function deploy(
).code !== ).code !==
0 0
) { ) {
throw new Error(`Error: Git checkout ${deploymentBranch} failed`); throw new Error(
`Running "git checkout ${deploymentBranch}" command failed.`,
);
} }
} }
@ -182,7 +186,7 @@ export default async function deploy(
await fs.copy(fromPath, toPath); await fs.copy(fromPath, toPath);
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Error: Copying build assets from "${fromPath}" to "${toPath}" failed with error '${error}'`, `Copying build assets from "${fromPath}" to "${toPath}" failed with error "${error}".`,
); );
} }
shell.cd(toPath); shell.cd(toPath);
@ -195,7 +199,7 @@ export default async function deploy(
if ( if (
shellExecLog(`git push --force origin ${deploymentBranch}`).code !== 0 shellExecLog(`git push --force origin ${deploymentBranch}`).code !== 0
) { ) {
throw new Error('Error: Git push failed'); throw new Error('Running "git push" command failed.');
} else if (commitResults.code === 0) { } else if (commitResults.code === 0) {
// The commit might return a non-zero value when site is up to date. // The commit might return a non-zero value when site is up to date.
let websiteURL = ''; let websiteURL = '';
@ -207,7 +211,7 @@ export default async function deploy(
// GitHub enterprise hosting. // GitHub enterprise hosting.
websiteURL = `https://${githubHost}/pages/${organizationName}/${projectName}/`; websiteURL = `https://${githubHost}/pages/${organizationName}/${projectName}/`;
} }
shell.echo(`Website is live at ${websiteURL}`); shell.echo(`Website is live at "${websiteURL}".`);
shell.exit(0); shell.exit(0);
} }
}; };

View file

@ -73,9 +73,9 @@ export default async function serve(
console.log( console.log(
boxen( boxen(
`${chalk.green( chalk.green(
`Serving "${cliOptions.dir}" directory at ${servingUrl + baseUrl}`, `Serving "${cliOptions.dir}" directory at "${servingUrl + baseUrl}".`,
)}`, ),
{ {
borderColor: 'green', borderColor: 'green',
padding: 1, padding: 1,

View file

@ -65,7 +65,9 @@ export default async function start(
const urls = prepareUrls(protocol, host, port); const urls = prepareUrls(protocol, host, port);
const openUrl = normalizeUrl([urls.localUrlForBrowser, baseUrl]); const openUrl = normalizeUrl([urls.localUrlForBrowser, baseUrl]);
console.log(chalk.cyanBright(`Docusaurus website is running at: ${openUrl}`)); console.log(
chalk.cyanBright(`Docusaurus website is running at "${openUrl}".`),
);
// Reload files processing. // Reload files processing.
const reload = debounce(() => { const reload = debounce(() => {
@ -74,7 +76,9 @@ export default async function start(
const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]); const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]);
if (newOpenUrl !== openUrl) { if (newOpenUrl !== openUrl) {
console.log( console.log(
chalk.cyanBright(`Docusaurus website is running at: ${newOpenUrl}`), chalk.cyanBright(
`Docusaurus website is running at "${newOpenUrl}".`,
),
); );
} }
}) })

View file

@ -100,11 +100,11 @@ function themeComponents(
const components = colorCode(themePath, plugin); const components = colorCode(themePath, plugin);
if (components.length === 0) { if (components.length === 0) {
return `${chalk.red('No component to swizzle')}`; return `${chalk.red('No component to swizzle.')}`;
} }
return ` return `
${chalk.cyan('Theme components available for swizzle')} ${chalk.cyan('Theme components available for swizzle.')}
${chalk.green('green =>')} safe: lower breaking change risk ${chalk.green('green =>')} safe: lower breaking change risk
${chalk.red('red =>')} unsafe: higher breaking change risk ${chalk.red('red =>')} unsafe: higher breaking change risk
@ -114,7 +114,7 @@ ${components.join('\n')}
} }
function formattedThemeNames(themeNames: string[]): string { function formattedThemeNames(themeNames: string[]): string {
return `Themes available for swizzle:\n${themeNames.join('\n')}`; return `Themes available for swizzle:\n- ${themeNames.join('\n- ')}`;
} }
function colorCode( function colorCode(

View file

@ -37,7 +37,7 @@ export function transformMarkdownHeadingLine(
slugger: GithubSlugger, slugger: GithubSlugger,
): string { ): string {
if (!line.startsWith('#')) { if (!line.startsWith('#')) {
throw new Error(`Line is not a markdown heading: ${line}`); throw new Error(`Line is not a Markdown heading: ${line}.`);
} }
const parsedHeading = parseMarkdownHeadingId(line); const parsedHeading = parseMarkdownHeadingId(line);
@ -118,7 +118,7 @@ export default async function writeHeadingIds(siteDir: string): Promise<void> {
if (pathsModified.length) { if (pathsModified.length) {
console.log( console.log(
chalk.green(`Heading ids added to markdown files (${ chalk.green(`Heading ids added to Markdown files (${
pathsModified.length pathsModified.length
}/${markdownFiles.length} files): }/${markdownFiles.length} files):
- ${pathsModified.join('\n- ')}`), - ${pathsModified.join('\n- ')}`),
@ -126,7 +126,7 @@ export default async function writeHeadingIds(siteDir: string): Promise<void> {
} else { } else {
console.log( console.log(
chalk.yellow( chalk.yellow(
`${markdownFiles.length} markdown files already have explicit heading ids`, `${markdownFiles.length} Markdown files already have explicit heading ids.`,
), ),
); );
} }

View file

@ -67,9 +67,8 @@ export default async function writeTranslations(
if (!context.i18n.locales.includes(locale)) { if (!context.i18n.locales.includes(locale)) {
throw new Error( throw new Error(
`Can't write-translation for locale that is not in the locale configuration file. `Can't write-translation for locale "${locale}" that is not in the locale configuration file.
Unknown locale=[${locale}]. Available locales are: ${context.i18n.locales.join(',')}.`,
Available locales=[${context.i18n.locales.join(',')}]`,
); );
} }

View file

@ -8,8 +8,8 @@ exports[`loadConfig website with incomplete siteConfig 1`] = `
exports[`loadConfig website with useless field (wrong field) in siteConfig 1`] = ` exports[`loadConfig website with useless field (wrong field) in siteConfig 1`] = `
"\\"favicon\\" is required "\\"favicon\\" is required
These field(s) [\\"useLessField\\",] are not recognized in docusaurus.config.js. These field(s) (\\"useLessField\\",) are not recognized in docusaurus.config.js.
If you still want these fields to be in your configuration, put them in the 'customFields' attribute. If you still want these fields to be in your configuration, put them in the \\"customFields\\" field.
See https://docusaurus.io/docs/docusaurus.config.js/#customfields" See https://docusaurus.io/docs/docusaurus.config.js/#customfields"
`; `;

View file

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`normalizeConfig should throw error for baseUrl without trailing \`/\` 1`] = ` exports[`normalizeConfig should throw error for baseUrl without trailing \`/\` 1`] = `
"\\"baseUrl\\" must be a string with a trailing \`/\` "\\"baseUrl\\" must be a string with a trailing slash.
" "
`; `;
@ -14,14 +14,14 @@ exports[`normalizeConfig should throw error for required fields 1`] = `
\\"presets\\" must be an array \\"presets\\" must be an array
\\"scripts\\" must be an array \\"scripts\\" must be an array
\\"stylesheets\\" must be an array \\"stylesheets\\" must be an array
These field(s) [\\"invalidField\\",] are not recognized in docusaurus.config.js. These field(s) (\\"invalidField\\",) are not recognized in docusaurus.config.js.
If you still want these fields to be in your configuration, put them in the 'customFields' attribute. If you still want these fields to be in your configuration, put them in the \\"customFields\\" field.
See https://docusaurus.io/docs/docusaurus.config.js/#customfields" See https://docusaurus.io/docs/docusaurus.config.js/#customfields"
`; `;
exports[`normalizeConfig should throw error for unknown field 1`] = ` exports[`normalizeConfig should throw error for unknown field 1`] = `
"These field(s) [\\"invalid\\",] are not recognized in docusaurus.config.js. "These field(s) (\\"invalid\\",) are not recognized in docusaurus.config.js.
If you still want these fields to be in your configuration, put them in the 'customFields' attribute. If you still want these fields to be in your configuration, put them in the \\"customFields\\" field.
See https://docusaurus.io/docs/docusaurus.config.js/#customfields" See https://docusaurus.io/docs/docusaurus.config.js/#customfields"
`; `;

View file

@ -55,7 +55,7 @@ describe('loadConfig', () => {
expect(() => { expect(() => {
loadConfig(siteDir); loadConfig(siteDir);
}).toThrowError( }).toThrowError(
/Config file "(.*?)__fixtures__[/\\]nonExisting[/\\]docusaurus.config.js" not found$/, /Config file at "(.*?)__fixtures__[/\\]nonExisting[/\\]docusaurus.config.js" not found.$/,
); );
}); });
}); });

View file

@ -174,7 +174,7 @@ describe('loadI18n', () => {
'it', 'it',
); );
expect(consoleSpy.mock.calls[0][0]).toMatch( expect(consoleSpy.mock.calls[0][0]).toMatch(
/The locale=it was not found in your site configuration/, /The locale "it" was not found in your site configuration/,
); );
}); });
}); });

View file

@ -75,7 +75,7 @@ describe('loadRoutes', () => {
expect(loadRoutes([routeConfigWithoutPath], '/')).rejects expect(loadRoutes([routeConfigWithoutPath], '/')).rejects
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
[Error: Invalid routeConfig (Path must be a string and component is required) [Error: Invalid route config: path must be a string and component is required.
{"component":"hello/world.js"}] {"component":"hello/world.js"}]
`); `);
@ -85,7 +85,7 @@ describe('loadRoutes', () => {
expect(loadRoutes([routeConfigWithoutComponent], '/')).rejects expect(loadRoutes([routeConfigWithoutComponent], '/')).rejects
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
[Error: Invalid routeConfig (Path must be a string and component is required) [Error: Invalid route config: path must be a string and component is required.
{"path":"/hello/world"}] {"path":"/hello/world"}]
`); `);
}); });

View file

@ -12,7 +12,7 @@ import {validateConfig} from './configValidation';
export default function loadConfig(configPath: string): DocusaurusConfig { export default function loadConfig(configPath: string): DocusaurusConfig {
if (!fs.existsSync(configPath)) { if (!fs.existsSync(configPath)) {
throw new Error(`Config file "${configPath}" not found`); throw new Error(`Config file at "${configPath}" not found.`);
} }
const loadedConfig = importFresh(configPath) as Partial<DocusaurusConfig>; const loadedConfig = importFresh(configPath) as Partial<DocusaurusConfig>;

View file

@ -125,7 +125,7 @@ export const ConfigSchema = Joi.object({
baseUrl: Joi.string() baseUrl: Joi.string()
.required() .required()
.regex(new RegExp('/$', 'm')) .regex(new RegExp('/$', 'm'))
.message('{{#label}} must be a string with a trailing `/`'), .message('{{#label}} must be a string with a trailing slash.'),
baseUrlIssueBanner: Joi.boolean().default(DEFAULT_CONFIG.baseUrlIssueBanner), baseUrlIssueBanner: Joi.boolean().default(DEFAULT_CONFIG.baseUrlIssueBanner),
favicon: Joi.string().required(), favicon: Joi.string().required(),
title: Joi.string().required(), title: Joi.string().required(),
@ -212,7 +212,7 @@ export function validateConfig(
'', '',
); );
formattedError = unknownFields formattedError = unknownFields
? `${formattedError}These field(s) [${unknownFields}] are not recognized in ${DEFAULT_CONFIG_FILE_NAME}.\nIf you still want these fields to be in your configuration, put them in the 'customFields' attribute.\nSee https://docusaurus.io/docs/docusaurus.config.js/#customfields` ? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${DEFAULT_CONFIG_FILE_NAME}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/docusaurus.config.js/#customfields`
: formattedError; : formattedError;
throw new Error(formattedError); throw new Error(formattedError);
} else { } else {

View file

@ -93,7 +93,7 @@ describe('htmlTagObjectToString', () => {
}, },
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"Error loading {\\"tagName\\":\\"endiliey\\",\\"attributes\\":{\\"this\\":\\"is invalid\\"}}, \\"endiliey\\" is not a valid HTML tags"`, `"Error loading {\\"tagName\\":\\"endiliey\\",\\"attributes\\":{\\"this\\":\\"is invalid\\"}}, \\"endiliey\\" is not a valid HTML tags."`,
); );
}); });
@ -103,7 +103,7 @@ describe('htmlTagObjectToString', () => {
tagName: true, tagName: true,
}), }),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"{\\"tagName\\":true} is not a valid HTML tag object. \\"tagName\\" must be defined as a string"`, `"{\\"tagName\\":true} is not a valid HTML tag object. \\"tagName\\" must be defined as a string."`,
); );
}); });
@ -111,13 +111,13 @@ describe('htmlTagObjectToString', () => {
expect(() => expect(() =>
htmlTagObjectToString('fooofofoofo'), htmlTagObjectToString('fooofofoofo'),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"\\"fooofofoofo\\" is not a valid HTML tag object"`, `"\\"fooofofoofo\\" is not a valid HTML tag object."`,
); );
expect(() => expect(() =>
htmlTagObjectToString(null), htmlTagObjectToString(null),
).toThrowErrorMatchingInlineSnapshot( ).toThrowErrorMatchingInlineSnapshot(
`"\\"null\\" is not a valid HTML tag object"`, `"\\"null\\" is not a valid HTML tag object."`,
); );
}); });
}); });

View file

@ -13,14 +13,14 @@ import escapeHTML from 'escape-html';
function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject { function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
if (!isPlainObject(val)) { if (!isPlainObject(val)) {
throw new Error(`"${val}" is not a valid HTML tag object`); throw new Error(`"${val}" is not a valid HTML tag object.`);
} }
// @ts-expect-error: If tagName doesn't exist, it will throw. // @ts-expect-error: If tagName doesn't exist, it will throw.
if (typeof val.tagName !== 'string') { if (typeof val.tagName !== 'string') {
throw new Error( throw new Error(
`${JSON.stringify( `${JSON.stringify(
val, val,
)} is not a valid HTML tag object. "tagName" must be defined as a string`, )} is not a valid HTML tag object. "tagName" must be defined as a string.`,
); );
} }
} }
@ -31,7 +31,7 @@ export default function htmlTagObjectToString(tagDefinition: unknown): string {
throw new Error( throw new Error(
`Error loading ${JSON.stringify(tagDefinition)}, "${ `Error loading ${JSON.stringify(tagDefinition)}, "${
tagDefinition.tagName tagDefinition.tagName
}" is not a valid HTML tags`, }" is not a valid HTML tags.`,
); );
} }
const isVoidTag = voidHtmlTags.indexOf(tagDefinition.tagName) !== -1; const isVoidTag = voidHtmlTags.indexOf(tagDefinition.tagName) !== -1;

View file

@ -46,9 +46,9 @@ export async function loadI18n(
if (!i18nConfig.locales.includes(currentLocale)) { if (!i18nConfig.locales.includes(currentLocale)) {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
`The locale=${currentLocale} was not found in your site configuration: config.i18n.locales=[${i18nConfig.locales.join( `The locale "${currentLocale}" was not found in your site configuration: Available locales are: ${i18nConfig.locales.join(
',', ',',
)}] )}.
Note: Docusaurus only support running one locale at a time.`, Note: Docusaurus only support running one locale at a time.`,
), ),
); );
@ -61,7 +61,7 @@ Note: Docusaurus only support running one locale at a time.`,
if (shouldWarnAboutNodeVersion(NODE_MAJOR_VERSION, locales)) { if (shouldWarnAboutNodeVersion(NODE_MAJOR_VERSION, locales)) {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
`To use Docusaurus i18n, it is strongly advised to use NodeJS >= 14 (instead of ${NODE_MAJOR_VERSION})`, `To use Docusaurus i18n, it is strongly advised to use Node.js 14 or later (instead of ${NODE_MAJOR_VERSION}).`,
), ),
); );
} }
@ -113,7 +113,7 @@ export function localizePath({
} }
// should never happen // should never happen
else { else {
throw new Error(`unhandled pathType=${pathType}`); throw new Error(`Unhandled path type "${pathType}".`);
} }
} else { } else {
return originalPath; return originalPath;

View file

@ -375,7 +375,7 @@ function checkDocusaurusPackagesVersion(siteMetadata: DocusaurusSiteMetadata) {
// It still could work with different versions // It still could work with different versions
console.warn( console.warn(
chalk.red( chalk.red(
`Bad ${plugin} version ${versionInfo.version}.\nAll official @docusaurus/* packages should have the exact same version as @docusaurus/core (${docusaurusVersion}).\nMaybe you want to check, or regenerate your yarn.lock or package-lock.json file?`, `Invalid ${plugin} version ${versionInfo.version}.\nAll official @docusaurus/* packages should have the exact same version as @docusaurus/core (${docusaurusVersion}).\nMaybe you want to check, or regenerate your yarn.lock or package-lock.json file?`,
), ),
); );
} }

View file

@ -1,16 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ensureUniquePluginInstanceIds reject multi instance plugins with same id 1`] = ` exports[`ensureUniquePluginInstanceIds reject multi instance plugins with same id 1`] = `
"Plugin plugin-docs is used 2 times with id=sameId. "Plugin \\"plugin-docs\\" is used 2 times with id sameId.
To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance." To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance."
`; `;
exports[`ensureUniquePluginInstanceIds reject multi instance plugins without id 1`] = ` exports[`ensureUniquePluginInstanceIds reject multi instance plugins without id 1`] = `
"Plugin plugin-docs is used 2 times with id=default. "Plugin \\"plugin-docs\\" is used 2 times with id default.
To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance." To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance."
`; `;
exports[`ensureUniquePluginInstanceIds reject multi instance plugins without id 2`] = ` exports[`ensureUniquePluginInstanceIds reject multi instance plugins without id 2`] = `
"Plugin plugin-docs is used 2 times with id=default. "Plugin \\"plugin-docs\\" is used 2 times with id default.
To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance." To use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance."
`; `;

View file

@ -201,7 +201,7 @@ export async function loadPlugins({
// TODO, 1 user reported usage of this lifecycle! https://github.com/facebook/docusaurus/issues/3918 // TODO, 1 user reported usage of this lifecycle! https://github.com/facebook/docusaurus/issues/3918
console.error( console.error(
chalk.red( chalk.red(
'plugin routesLoaded lifecycle is deprecated. If you think we should keep this lifecycle, please report here: https://github.com/facebook/docusaurus/issues/3918', 'Plugin routesLoaded lifecycle is deprecated. If you think we should keep this lifecycle, please report here: https://github.com/facebook/docusaurus/issues/3918',
), ),
); );

View file

@ -90,7 +90,7 @@ function normalizePluginConfig(
} }
throw new Error( throw new Error(
`Unexpected: cant load plugin for plugin config = ${JSON.stringify( `Unexpected: can't load plugin for following plugin config.\n${JSON.stringify(
pluginConfig, pluginConfig,
)}`, )}`,
); );

View file

@ -22,7 +22,7 @@ export function ensureUniquePluginInstanceIds(plugins: InitPlugin[]): void {
([pluginId, pluginInstancesWithId]) => { ([pluginId, pluginInstancesWithId]) => {
if (pluginInstancesWithId.length !== 1) { if (pluginInstancesWithId.length !== 1) {
throw new Error( throw new Error(
`Plugin ${pluginName} is used ${pluginInstancesWithId.length} times with id=${pluginId}.\nTo use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance.`, `Plugin "${pluginName}" is used ${pluginInstancesWithId.length} times with id ${pluginId}.\nTo use the same plugin multiple times on a Docusaurus site, you need to assign a unique id to each plugin instance.`,
); );
} }
}, },

View file

@ -110,7 +110,7 @@ export default async function loadRoutes(
if (!isString(routePath) || !component) { if (!isString(routePath) || !component) {
throw new Error( throw new Error(
`Invalid routeConfig (Path must be a string and component is required) \n${JSON.stringify( `Invalid route config: path must be a string and component is required.\n${JSON.stringify(
routeConfig, routeConfig,
)}`, )}`,
); );

View file

@ -266,7 +266,7 @@ describe('writeTranslationFileContent', () => {
key1: {message: 'key1 message'}, key1: {message: 'key1 message'},
}, },
}), }),
).rejects.toThrowError(/Invalid translation file at path/); ).rejects.toThrowError(/Invalid translation file at/);
}); });
}); });

View file

@ -56,9 +56,7 @@ export async function readTranslationFileContent(
ensureTranslationFileContent(content); ensureTranslationFileContent(content);
return content; return content;
} catch (e) { } catch (e) {
throw new Error( throw new Error(`Invalid translation file at ${filePath}.\n${e.message}`);
`Invalid translation file at path=${filePath}.\n${e.message}`,
);
} }
} }
return undefined; return undefined;
@ -135,9 +133,9 @@ Maybe you should remove them?
.padStart( .padStart(
3, 3,
' ', ' ',
)} translations will be written at ${toMessageRelativeFilePath( )} translations will be written at "${toMessageRelativeFilePath(
filePath, filePath,
)}`, )}".`,
); );
await fs.ensureDir(path.dirname(filePath)); await fs.ensureDir(path.dirname(filePath));
await fs.writeFile(filePath, JSON.stringify(mergedContent, null, 2)); await fs.writeFile(filePath, JSON.stringify(mergedContent, null, 2));
@ -183,7 +181,7 @@ export async function writeCodeTranslations(
function addTranslationFileExtension(translationFilePath: string) { function addTranslationFileExtension(translationFilePath: string) {
if (translationFilePath.endsWith('.json')) { if (translationFilePath.endsWith('.json')) {
throw new Error( throw new Error(
`Translation file path does not need to end with .json, we addt the extension automatically. translationFilePath=${translationFilePath}`, `Translation file path at "${translationFilePath}" does not need to end with ".json", we add the extension automatically.`,
); );
} }
return `${translationFilePath}.json`; return `${translationFilePath}.json`;

View file

@ -244,7 +244,7 @@ class CleanWebpackPlugin {
if (needsForce) { if (needsForce) {
const message = const message =
'clean-webpack-plugin: Cannot delete files/folders outside the current working directory. Can be overridden with the `dangerouslyAllowCleanPatternsOutsideProject` option.'; 'clean-webpack-plugin: Cannot delete files/folders outside the current working directory. Can be overridden with the "dangerouslyAllowCleanPatternsOutsideProject" option.';
throw new Error(message); throw new Error(message);
} }

View file

@ -167,7 +167,7 @@ export const getCustomizableJSLoader = (
const warnBabelLoaderOnce = memoize(function () { const warnBabelLoaderOnce = memoize(function () {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
'Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): getBabelLoader(isServer) is now deprecated in favor of getJSLoader({isServer})', 'Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): "getBabelLoader(isServer)" is now deprecated in favor of "getJSLoader({isServer})".',
), ),
); );
}); });
@ -183,7 +183,7 @@ const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
const warnCacheLoaderOnce = memoize(function () { const warnCacheLoaderOnce = memoize(function () {
console.warn( console.warn(
chalk.yellow( chalk.yellow(
'Docusaurus uses Webpack 5 and getCacheLoader() usage is now deprecated', 'Docusaurus uses Webpack 5 and getCacheLoader() usage is now deprecated.',
), ),
); );
}); });
@ -288,7 +288,7 @@ export function compile(config: Configuration[]): Promise<void> {
compiler.close((errClose) => { compiler.close((errClose) => {
if (errClose) { if (errClose) {
console.error( console.error(
chalk.red('Error while closing Webpack compiler', errClose), chalk.red('Error while closing Webpack compiler:', errClose),
); );
reject(errClose); reject(errClose);
} else { } else {