Skip to content

Commit b0b6516

Browse files
committed
fix(redirect): tolerate trailing slash difference if config is undefined
1 parent a492025 commit b0b6516

File tree

3 files changed

+135
-9
lines changed

3 files changed

+135
-9
lines changed

packages/docusaurus-plugin-client-redirects/src/__tests__/__snapshots__/collectRedirects.test.ts.snap

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`collectRedirects throw if plugin option redirects contain invalid to paths 1`] = `
4-
"You are trying to create client-side redirections to paths that do not exist:
5-
- /this/path/does/not/exist2
4+
"You are trying to create client-side redirections to invalid paths.
5+
6+
These paths are redirected to but do not exist:
67
- /this/path/does/not/exist2
78
89
Valid paths you can redirect to:
@@ -12,6 +13,22 @@ Valid paths you can redirect to:
1213
"
1314
`;
1415

16+
exports[`collectRedirects throw if plugin option redirects contain to paths with mismatching trailing slash 1`] = `
17+
"You are trying to create client-side redirections to invalid paths.
18+
19+
These paths do exist, but because you have explicitly set trailingSlash=false, you need to write the path without trailing slash:
20+
- /someExistingPath/
21+
"
22+
`;
23+
24+
exports[`collectRedirects throw if plugin option redirects contain to paths with mismatching trailing slash 2`] = `
25+
"You are trying to create client-side redirections to invalid paths.
26+
27+
These paths do exist, but because you have explicitly set trailingSlash=true, you need to write the path with trailing slash:
28+
- /someExistingPath
29+
"
30+
`;
31+
1532
exports[`collectRedirects throws if redirect creator creates array of array redirect 1`] = `
1633
"Some created redirects are invalid:
1734
- {"from":["/fromPath"],"to":"/"} => Validation error: "from" must be a string

packages/docusaurus-plugin-client-redirects/src/__tests__/collectRedirects.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,69 @@ describe('collectRedirects', () => {
220220
).toThrowErrorMatchingSnapshot();
221221
});
222222

223+
it('tolerates mismatched trailing slash if option is undefined', () => {
224+
expect(
225+
collectRedirects(
226+
createTestPluginContext(
227+
{
228+
redirects: [
229+
{
230+
from: '/someLegacyPath',
231+
to: '/somePath',
232+
},
233+
],
234+
},
235+
['/', '/somePath/'],
236+
{trailingSlash: undefined},
237+
),
238+
undefined,
239+
),
240+
).toEqual([
241+
{
242+
from: '/someLegacyPath',
243+
to: '/somePath',
244+
},
245+
]);
246+
});
247+
248+
it('throw if plugin option redirects contain to paths with mismatching trailing slash', () => {
249+
expect(() =>
250+
collectRedirects(
251+
createTestPluginContext(
252+
{
253+
redirects: [
254+
{
255+
from: '/someLegacyPath',
256+
to: '/someExistingPath/',
257+
},
258+
],
259+
},
260+
['/', '/someExistingPath', '/anotherExistingPath'],
261+
{trailingSlash: false},
262+
),
263+
undefined,
264+
),
265+
).toThrowErrorMatchingSnapshot();
266+
267+
expect(() =>
268+
collectRedirects(
269+
createTestPluginContext(
270+
{
271+
redirects: [
272+
{
273+
from: '/someLegacyPath',
274+
to: '/someExistingPath',
275+
},
276+
],
277+
},
278+
['/', '/someExistingPath/', '/anotherExistingPath/'],
279+
{trailingSlash: true},
280+
),
281+
undefined,
282+
),
283+
).toThrowErrorMatchingSnapshot();
284+
});
285+
223286
it('collects redirects with custom redirect creator', () => {
224287
expect(
225288
collectRedirects(

packages/docusaurus-plugin-client-redirects/src/collectRedirects.ts

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import _ from 'lodash';
99
import logger from '@docusaurus/logger';
10+
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils';
1011
import {applyTrailingSlash} from '@docusaurus/utils-common';
1112
import {
1213
createFromExtensionsRedirects,
@@ -80,16 +81,61 @@ function validateCollectedRedirects(
8081

8182
const allowedToPaths = pluginContext.relativeRoutesPaths;
8283
const toPaths = redirects.map((redirect) => redirect.to);
83-
const illegalToPaths = _.difference(toPaths, allowedToPaths);
84-
if (illegalToPaths.length > 0) {
85-
throw new Error(
86-
`You are trying to create client-side redirections to paths that do not exist:
87-
- ${illegalToPaths.join('\n- ')}
84+
const trailingSlashConfig = pluginContext.siteConfig.trailingSlash;
85+
// Key is the path, value is whether a valid toPath with a different trailing
86+
// slash exists; if the key doesn't exist it means it's valid
87+
const differByTrailSlash = new Map(toPaths.map((path) => [path, false]));
88+
allowedToPaths.forEach((toPath) => {
89+
if (differByTrailSlash.has(toPath)) {
90+
differByTrailSlash.delete(toPath);
91+
return;
92+
}
93+
if (differByTrailSlash.has(removeTrailingSlash(toPath))) {
94+
if (trailingSlashConfig === true) {
95+
differByTrailSlash.set(removeTrailingSlash(toPath), true);
96+
} else {
97+
differByTrailSlash.delete(removeTrailingSlash(toPath));
98+
}
99+
} else if (differByTrailSlash.has(addTrailingSlash(toPath))) {
100+
if (trailingSlashConfig === false) {
101+
differByTrailSlash.set(addTrailingSlash(toPath), true);
102+
} else {
103+
differByTrailSlash.delete(addTrailingSlash(toPath));
104+
}
105+
}
106+
});
107+
if (differByTrailSlash.size > 0) {
108+
console.log(differByTrailSlash);
109+
const errors = Array.from(differByTrailSlash.entries());
110+
111+
let message =
112+
'You are trying to create client-side redirections to invalid paths.\n';
113+
114+
const [trailingSlashIssues, invalidPaths] = _.partition(
115+
errors,
116+
([, differ]) => differ,
117+
);
118+
119+
if (trailingSlashIssues.length) {
120+
message += `
121+
These paths do exist, but because you have explicitly set trailingSlash=${trailingSlashConfig}, you need to write the path ${
122+
trailingSlashConfig ? 'with trailing slash' : 'without trailing slash'
123+
}:
124+
- ${trailingSlashIssues.map(([p]) => p).join('\n- ')}
125+
`;
126+
}
127+
128+
if (invalidPaths.length) {
129+
message += `
130+
These paths are redirected to but do not exist:
131+
- ${invalidPaths.map(([p]) => p).join('\n- ')}
88132
89133
Valid paths you can redirect to:
90134
- ${allowedToPaths.join('\n- ')}
91-
`,
92-
);
135+
`;
136+
}
137+
138+
throw new Error(message);
93139
}
94140
}
95141

0 commit comments

Comments
 (0)