Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,8 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

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:
- /this/path/does/not/exist2
"You are trying to create client-side redirections to invalid paths.

These paths are redirected to but do not exist:
- /this/path/does/not/exist2

Valid paths you can redirect to:
Expand All @@ -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`] = `
"Some created redirects are invalid:
- {"from":["/fromPath"],"to":"/"} => Validation error: "from" must be a string
Expand Down
Expand Up @@ -220,6 +220,69 @@ describe('collectRedirects', () => {
).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', () => {
expect(
collectRedirects(
Expand Down
Expand Up @@ -7,6 +7,7 @@

import _ from 'lodash';
import logger from '@docusaurus/logger';
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils';
import {applyTrailingSlash} from '@docusaurus/utils-common';
import {
createFromExtensionsRedirects,
Expand Down Expand Up @@ -80,16 +81,59 @@ function validateCollectedRedirects(

const allowedToPaths = pluginContext.relativeRoutesPaths;
const toPaths = redirects.map((redirect) => redirect.to);
const illegalToPaths = _.difference(toPaths, allowedToPaths);
if (illegalToPaths.length > 0) {
throw new Error(
`You are trying to create client-side redirections to paths that do not exist:
- ${illegalToPaths.join('\n- ')}
const trailingSlashConfig = pluginContext.siteConfig.trailingSlash;
// Key is the path, value is whether a valid toPath with a different trailing
// slash exists; if the key doesn't exist it means it's valid
const differByTrailSlash = new Map(toPaths.map((path) => [path, false]));
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:
- ${allowedToPaths.join('\n- ')}
`,
);
`;
}

throw new Error(message);
}
}

Expand Down