mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
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:
parent
8501db78a1
commit
41d9288e3d
86 changed files with 382 additions and 339 deletions
|
@ -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,
|
||||||
|
|
|
@ -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!');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`] = `
|
||||||
"
|
"
|
||||||
|
|
|
@ -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`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}).`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -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"`;
|
||||||
|
|
||||||
|
|
|
@ -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'];
|
||||||
|
|
|
@ -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.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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}.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}.`);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -453,7 +453,7 @@ describe('simple site', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}).toThrowErrorMatchingInlineSnapshot(
|
}).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"Document id [Hello/world] cannot include \\"/\\"."`,
|
`"Document id \\"Hello/world\\" cannot include slash."`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
}`,
|
}.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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\\"."`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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!`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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- ')}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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- ')}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 () => {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -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}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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'),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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.',
|
||||||
);
|
);
|
||||||
|
|
|
@ -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`,
|
||||||
),
|
),
|
||||||
|
|
|
@ -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]"
|
||||||
|
|
|
@ -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."`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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}.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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."`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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}".`,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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.`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(',')}]`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -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.$/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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"}]
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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."`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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?`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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."
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -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',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
|
|
|
@ -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.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
|
|
|
@ -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/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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`;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue