fix(redirect): tolerate trailing slash difference if config is undefined (#8067)

This commit is contained in:
Joshua Chen 2022-09-08 11:15:52 -04:00 committed by GitHub
parent 710c0c58f0
commit 73d0ede21a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 133 additions and 9 deletions

View file

@ -1,8 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`collectRedirects throw if plugin option redirects contain invalid to paths 1`] = ` exports[`collectRedirects throw if plugin option redirects contain invalid to paths 1`] = `
"You are trying to create client-side redirections to paths that do not exist: "You are trying to create client-side redirections to invalid paths.
- /this/path/does/not/exist2
These paths are redirected to but do not exist:
- /this/path/does/not/exist2 - /this/path/does/not/exist2
Valid paths you can redirect to: Valid paths you can redirect to:
@ -12,6 +13,22 @@ Valid paths you can redirect to:
" "
`; `;
exports[`collectRedirects throw if plugin option redirects contain to paths with mismatching trailing slash 1`] = `
"You are trying to create client-side redirections to invalid paths.
These paths do exist, but because you have explicitly set trailingSlash=false, you need to write the path without trailing slash:
- /someExistingPath/
"
`;
exports[`collectRedirects throw if plugin option redirects contain to paths with mismatching trailing slash 2`] = `
"You are trying to create client-side redirections to invalid paths.
These paths do exist, but because you have explicitly set trailingSlash=true, you need to write the path with trailing slash:
- /someExistingPath
"
`;
exports[`collectRedirects throws if redirect creator creates array of array redirect 1`] = ` exports[`collectRedirects throws if redirect creator creates array of array redirect 1`] = `
"Some created redirects are invalid: "Some created redirects are invalid:
- {"from":["/fromPath"],"to":"/"} => Validation error: "from" must be a string - {"from":["/fromPath"],"to":"/"} => Validation error: "from" must be a string

View file

@ -220,6 +220,69 @@ describe('collectRedirects', () => {
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
}); });
it('tolerates mismatched trailing slash if option is undefined', () => {
expect(
collectRedirects(
createTestPluginContext(
{
redirects: [
{
from: '/someLegacyPath',
to: '/somePath',
},
],
},
['/', '/somePath/'],
{trailingSlash: undefined},
),
undefined,
),
).toEqual([
{
from: '/someLegacyPath',
to: '/somePath',
},
]);
});
it('throw if plugin option redirects contain to paths with mismatching trailing slash', () => {
expect(() =>
collectRedirects(
createTestPluginContext(
{
redirects: [
{
from: '/someLegacyPath',
to: '/someExistingPath/',
},
],
},
['/', '/someExistingPath', '/anotherExistingPath'],
{trailingSlash: false},
),
undefined,
),
).toThrowErrorMatchingSnapshot();
expect(() =>
collectRedirects(
createTestPluginContext(
{
redirects: [
{
from: '/someLegacyPath',
to: '/someExistingPath',
},
],
},
['/', '/someExistingPath/', '/anotherExistingPath/'],
{trailingSlash: true},
),
undefined,
),
).toThrowErrorMatchingSnapshot();
});
it('collects redirects with custom redirect creator', () => { it('collects redirects with custom redirect creator', () => {
expect( expect(
collectRedirects( collectRedirects(

View file

@ -7,6 +7,7 @@
import _ from 'lodash'; import _ from 'lodash';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils';
import {applyTrailingSlash} from '@docusaurus/utils-common'; import {applyTrailingSlash} from '@docusaurus/utils-common';
import { import {
createFromExtensionsRedirects, createFromExtensionsRedirects,
@ -80,16 +81,59 @@ function validateCollectedRedirects(
const allowedToPaths = pluginContext.relativeRoutesPaths; const allowedToPaths = pluginContext.relativeRoutesPaths;
const toPaths = redirects.map((redirect) => redirect.to); const toPaths = redirects.map((redirect) => redirect.to);
const illegalToPaths = _.difference(toPaths, allowedToPaths); const trailingSlashConfig = pluginContext.siteConfig.trailingSlash;
if (illegalToPaths.length > 0) { // Key is the path, value is whether a valid toPath with a different trailing
throw new Error( // slash exists; if the key doesn't exist it means it's valid
`You are trying to create client-side redirections to paths that do not exist: const differByTrailSlash = new Map(toPaths.map((path) => [path, false]));
- ${illegalToPaths.join('\n- ')} allowedToPaths.forEach((toPath) => {
if (differByTrailSlash.has(toPath)) {
differByTrailSlash.delete(toPath);
} else if (differByTrailSlash.has(removeTrailingSlash(toPath))) {
if (trailingSlashConfig === true) {
differByTrailSlash.set(removeTrailingSlash(toPath), true);
} else {
differByTrailSlash.delete(removeTrailingSlash(toPath));
}
} else if (differByTrailSlash.has(addTrailingSlash(toPath))) {
if (trailingSlashConfig === false) {
differByTrailSlash.set(addTrailingSlash(toPath), true);
} else {
differByTrailSlash.delete(addTrailingSlash(toPath));
}
}
});
if (differByTrailSlash.size > 0) {
console.log(differByTrailSlash);
const errors = Array.from(differByTrailSlash.entries());
let message =
'You are trying to create client-side redirections to invalid paths.\n';
const [trailingSlashIssues, invalidPaths] = _.partition(
errors,
([, differ]) => differ,
);
if (trailingSlashIssues.length) {
message += `
These paths do exist, but because you have explicitly set trailingSlash=${trailingSlashConfig}, you need to write the path ${
trailingSlashConfig ? 'with trailing slash' : 'without trailing slash'
}:
- ${trailingSlashIssues.map(([p]) => p).join('\n- ')}
`;
}
if (invalidPaths.length) {
message += `
These paths are redirected to but do not exist:
- ${invalidPaths.map(([p]) => p).join('\n- ')}
Valid paths you can redirect to: Valid paths you can redirect to:
- ${allowedToPaths.join('\n- ')} - ${allowedToPaths.join('\n- ')}
`, `;
); }
throw new Error(message);
} }
} }