mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-02 00:09:48 +02:00
rename fromRoutePath/toRoutePath to simply from/to
This commit is contained in:
parent
06673ee8c3
commit
0ac5a66a1f
11 changed files with 103 additions and 107 deletions
|
@ -14,7 +14,7 @@ Valid paths you can redirect to:
|
|||
|
||||
exports[`collectRedirects should throw if redirect creator creates array of array redirect 1`] = `
|
||||
"Some created redirects are invalid:
|
||||
- {\\"fromRoutePath\\":[\\"/fromPath\\"],\\"toRoutePath\\":\\"/\\"} => Validation error: fromRoutePath must be a \`string\` type, but the final value was: \`[
|
||||
- {\\"from\\":[\\"/fromPath\\"],\\"to\\":\\"/\\"} => Validation error: from must be a \`string\` type, but the final value was: \`[
|
||||
\\"\\\\\\"/fromPath\\\\\\"\\"
|
||||
]\`.
|
||||
"
|
||||
|
@ -22,8 +22,8 @@ exports[`collectRedirects should throw if redirect creator creates array of arra
|
|||
|
||||
exports[`collectRedirects should throw if redirect creator creates invalid redirects 1`] = `
|
||||
"Some created redirects are invalid:
|
||||
- {\\"fromRoutePath\\":\\"https://google.com/\\",\\"toRoutePath\\":\\"/\\"} => Validation error: fromRoutePath is not a valid pathname. Pathname should start with / and not contain any domain or query string
|
||||
- {\\"fromRoutePath\\":\\"//abc\\",\\"toRoutePath\\":\\"/\\"} => Validation error: fromRoutePath is not a valid pathname. Pathname should start with / and not contain any domain or query string
|
||||
- {\\"fromRoutePath\\":\\"/def?queryString=toto\\",\\"toRoutePath\\":\\"/\\"} => Validation error: fromRoutePath 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 / 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\\":\\"/def?queryString=toto\\",\\"to\\":\\"/\\"} => Validation error: from is not a valid pathname. Pathname should start with / and not contain any domain or query string
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`validateRedirect throw for bad redirects 1`] = `"{\\"fromRoutePath\\":\\"https://fb.com/fromSomePath\\",\\"toRoutePath\\":\\"/toSomePath\\"} => Validation error: fromRoutePath 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 / and not contain any domain or query string"`;
|
||||
|
||||
exports[`validateRedirect throw for bad redirects 2`] = `"{\\"fromRoutePath\\":\\"/fromSomePath\\",\\"toRoutePath\\":\\"https://fb.com/toSomePath\\"} => Validation error: toRoutePath 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 / and not contain any domain or query string"`;
|
||||
|
||||
exports[`validateRedirect throw for bad redirects 3`] = `"{\\"fromRoutePath\\":\\"/fromSomePath\\",\\"toRoutePath\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: toRoutePath 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 / and not contain any domain or query string"`;
|
||||
|
||||
exports[`validateRedirect throw for bad redirects 4`] = `"{\\"fromRoutePath\\":null,\\"toRoutePath\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: toRoutePath is not a valid pathname. Pathname should start with / and not contain any domain or query string"`;
|
||||
exports[`validateRedirect throw for bad redirects 4`] = `"{\\"from\\":null,\\"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 5`] = `"{\\"fromRoutePath\\":[\\"heyho\\"],\\"toRoutePath\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: toRoutePath is not a valid pathname. Pathname should start with / and not contain any domain or query string"`;
|
||||
exports[`validateRedirect throw for bad redirects 5`] = `"{\\"from\\":[\\"heyho\\"],\\"to\\":\\"/toSomePath?queryString=xyz\\"} => Validation error: to is not a valid pathname. Pathname should start with / and not contain any domain or query string"`;
|
||||
|
|
|
@ -45,12 +45,12 @@ describe('collectRedirects', () => {
|
|||
),
|
||||
).toEqual([
|
||||
{
|
||||
fromRoutePath: '/somePath.html',
|
||||
toRoutePath: '/somePath',
|
||||
from: '/somePath.html',
|
||||
to: '/somePath',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/somePath.exe',
|
||||
toRoutePath: '/somePath',
|
||||
from: '/somePath.exe',
|
||||
to: '/somePath',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -67,8 +67,8 @@ describe('collectRedirects', () => {
|
|||
),
|
||||
).toEqual([
|
||||
{
|
||||
fromRoutePath: '/otherPath',
|
||||
toRoutePath: '/otherPath.html',
|
||||
from: '/otherPath',
|
||||
to: '/otherPath.html',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -94,16 +94,16 @@ describe('collectRedirects', () => {
|
|||
),
|
||||
).toEqual([
|
||||
{
|
||||
fromRoutePath: '/someLegacyPath',
|
||||
toRoutePath: '/somePath',
|
||||
from: '/someLegacyPath',
|
||||
to: '/somePath',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/someLegacyPathArray1',
|
||||
toRoutePath: '/',
|
||||
from: '/someLegacyPathArray1',
|
||||
to: '/',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/someLegacyPathArray2',
|
||||
toRoutePath: '/',
|
||||
from: '/someLegacyPathArray2',
|
||||
to: '/',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -151,30 +151,30 @@ describe('collectRedirects', () => {
|
|||
),
|
||||
).toEqual([
|
||||
{
|
||||
fromRoutePath: '/some/path/suffix1',
|
||||
toRoutePath: '/',
|
||||
from: '/some/path/suffix1',
|
||||
to: '/',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/some/other/path/suffix2',
|
||||
toRoutePath: '/',
|
||||
from: '/some/other/path/suffix2',
|
||||
to: '/',
|
||||
},
|
||||
|
||||
{
|
||||
fromRoutePath: '/testpath/some/path/suffix1',
|
||||
toRoutePath: '/testpath',
|
||||
from: '/testpath/some/path/suffix1',
|
||||
to: '/testpath',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/testpath/some/other/path/suffix2',
|
||||
toRoutePath: '/testpath',
|
||||
from: '/testpath/some/other/path/suffix2',
|
||||
to: '/testpath',
|
||||
},
|
||||
|
||||
{
|
||||
fromRoutePath: '/otherPath.html/some/path/suffix1',
|
||||
toRoutePath: '/otherPath.html',
|
||||
from: '/otherPath.html/some/path/suffix1',
|
||||
to: '/otherPath.html',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/otherPath.html/some/other/path/suffix2',
|
||||
toRoutePath: '/otherPath.html',
|
||||
from: '/otherPath.html/some/other/path/suffix2',
|
||||
to: '/otherPath.html',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
@ -239,16 +239,16 @@ describe('collectRedirects', () => {
|
|||
),
|
||||
).toEqual([
|
||||
{
|
||||
fromRoutePath: '/toShouldWork.html',
|
||||
toRoutePath: '/toShouldWork',
|
||||
from: '/toShouldWork.html',
|
||||
to: '/toShouldWork',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/toShouldWork.exe',
|
||||
toRoutePath: '/toShouldWork',
|
||||
from: '/toShouldWork.exe',
|
||||
to: '/toShouldWork',
|
||||
},
|
||||
{
|
||||
fromRoutePath: '/fromShouldWork',
|
||||
toRoutePath: '/fromShouldWork.html',
|
||||
from: '/fromShouldWork',
|
||||
to: '/fromShouldWork.html',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -55,10 +55,10 @@ describe('createToExtensionsRedirects', () => {
|
|||
expect(createToExtensionsRedirects([''], ext)).toEqual([]);
|
||||
expect(createToExtensionsRedirects(['/'], ext)).toEqual([]);
|
||||
expect(createToExtensionsRedirects(['/abc.html'], ext)).toEqual([
|
||||
{fromRoutePath: '/abc', toRoutePath: '/abc.html'},
|
||||
{from: '/abc', to: '/abc.html'},
|
||||
]);
|
||||
expect(createToExtensionsRedirects(['/abc.htm'], ext)).toEqual([
|
||||
{fromRoutePath: '/abc', toRoutePath: '/abc.htm'},
|
||||
{from: '/abc', to: '/abc.htm'},
|
||||
]);
|
||||
expect(createToExtensionsRedirects(['/abc.xyz'], ext)).toEqual([]);
|
||||
});
|
||||
|
@ -79,8 +79,8 @@ describe('createFromExtensionsRedirects', () => {
|
|||
expect(createFromExtensionsRedirects([''], ext)).toEqual([]);
|
||||
expect(createFromExtensionsRedirects(['/'], ext)).toEqual([]);
|
||||
expect(createFromExtensionsRedirects(['/abc'], ext)).toEqual([
|
||||
{fromRoutePath: '/abc.html', toRoutePath: '/abc'},
|
||||
{fromRoutePath: '/abc.htm', toRoutePath: '/abc'},
|
||||
{from: '/abc.html', to: '/abc'},
|
||||
{from: '/abc.htm', to: '/abc'},
|
||||
]);
|
||||
expect(createFromExtensionsRedirects(['/def.html'], ext)).toEqual([]);
|
||||
expect(createFromExtensionsRedirects(['/def/'], ext)).toEqual([]);
|
||||
|
|
|
@ -10,56 +10,56 @@ import {validateRedirect} from '../redirectValidation';
|
|||
describe('validateRedirect', () => {
|
||||
test('validate good redirects without throwing', () => {
|
||||
validateRedirect({
|
||||
fromRoutePath: '/fromSomePath',
|
||||
toRoutePath: '/toSomePath',
|
||||
from: '/fromSomePath',
|
||||
to: '/toSomePath',
|
||||
});
|
||||
validateRedirect({
|
||||
fromRoutePath: '/from/Some/Path',
|
||||
toRoutePath: '/toSomePath',
|
||||
from: '/from/Some/Path',
|
||||
to: '/toSomePath',
|
||||
});
|
||||
validateRedirect({
|
||||
fromRoutePath: '/fromSomePath',
|
||||
toRoutePath: '/toSomePath',
|
||||
from: '/fromSomePath',
|
||||
to: '/toSomePath',
|
||||
});
|
||||
validateRedirect({
|
||||
fromRoutePath: '/fromSomePath',
|
||||
toRoutePath: '/to/Some/Path',
|
||||
from: '/fromSomePath',
|
||||
to: '/to/Some/Path',
|
||||
});
|
||||
});
|
||||
|
||||
test('throw for bad redirects', () => {
|
||||
expect(() =>
|
||||
validateRedirect({
|
||||
fromRoutePath: 'https://fb.com/fromSomePath',
|
||||
toRoutePath: '/toSomePath',
|
||||
from: 'https://fb.com/fromSomePath',
|
||||
to: '/toSomePath',
|
||||
}),
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
|
||||
expect(() =>
|
||||
validateRedirect({
|
||||
fromRoutePath: '/fromSomePath',
|
||||
toRoutePath: 'https://fb.com/toSomePath',
|
||||
from: '/fromSomePath',
|
||||
to: 'https://fb.com/toSomePath',
|
||||
}),
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
|
||||
expect(() =>
|
||||
validateRedirect({
|
||||
fromRoutePath: '/fromSomePath',
|
||||
toRoutePath: '/toSomePath?queryString=xyz',
|
||||
from: '/fromSomePath',
|
||||
to: '/toSomePath?queryString=xyz',
|
||||
}),
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
|
||||
expect(() =>
|
||||
validateRedirect({
|
||||
fromRoutePath: null as any,
|
||||
toRoutePath: '/toSomePath?queryString=xyz',
|
||||
from: null as any,
|
||||
to: '/toSomePath?queryString=xyz',
|
||||
}),
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
|
||||
expect(() =>
|
||||
validateRedirect({
|
||||
fromRoutePath: ['heyho'] as any,
|
||||
toRoutePath: '/toSomePath?queryString=xyz',
|
||||
from: ['heyho'] as any,
|
||||
to: '/toSomePath?queryString=xyz',
|
||||
}),
|
||||
).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
|
|
@ -20,9 +20,9 @@ describe('toRedirectFilesMetadata', () => {
|
|||
|
||||
const redirectFiles = toRedirectFilesMetadata(
|
||||
[
|
||||
{fromRoutePath: '/abc.html', toRoutePath: '/abc'},
|
||||
{fromRoutePath: '/def', toRoutePath: '/def.html'},
|
||||
{fromRoutePath: '/xyz', toRoutePath: '/'},
|
||||
{from: '/abc.html', to: '/abc'},
|
||||
{from: '/def', to: '/def.html'},
|
||||
{from: '/xyz', to: '/'},
|
||||
],
|
||||
pluginContext,
|
||||
);
|
||||
|
@ -44,7 +44,7 @@ describe('toRedirectFilesMetadata', () => {
|
|||
baseUrl: '/',
|
||||
};
|
||||
const redirectFiles = toRedirectFilesMetadata(
|
||||
[{fromRoutePath: '/abc.html', toRoutePath: '/abc'}],
|
||||
[{from: '/abc.html', to: '/abc'}],
|
||||
pluginContext,
|
||||
);
|
||||
expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot(
|
||||
|
@ -58,7 +58,7 @@ describe('toRedirectFilesMetadata', () => {
|
|||
baseUrl: '',
|
||||
};
|
||||
const redirectFiles = toRedirectFilesMetadata(
|
||||
[{fromRoutePath: '/abc.html', toRoutePath: '/abc'}],
|
||||
[{from: '/abc.html', to: '/abc'}],
|
||||
pluginContext,
|
||||
);
|
||||
expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot(
|
||||
|
|
|
@ -50,7 +50,7 @@ function validateCollectedRedirects(
|
|||
}
|
||||
|
||||
const allowedToPaths = pluginContext.routesPaths;
|
||||
const toPaths = redirects.map((redirect) => redirect.toRoutePath);
|
||||
const toPaths = redirects.map((redirect) => redirect.to);
|
||||
const illegalToPaths = difference(toPaths, allowedToPaths);
|
||||
if (illegalToPaths.length > 0) {
|
||||
throw new Error(
|
||||
|
@ -70,25 +70,25 @@ function filterUnwantedRedirects(
|
|||
): RedirectMetadata[] {
|
||||
// we don't want to create twice the same redirect
|
||||
// that would lead to writing twice the same html redirection file
|
||||
Object.entries(
|
||||
groupBy(redirects, (redirect) => redirect.fromRoutePath),
|
||||
).forEach(([from, groupedFromRedirects]) => {
|
||||
if (groupedFromRedirects.length > 1) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`@docusaurus/plugin-client-redirects: multiple redirects are created with the same "from" pathname=${from}
|
||||
Object.entries(groupBy(redirects, (redirect) => redirect.from)).forEach(
|
||||
([from, groupedFromRedirects]) => {
|
||||
if (groupedFromRedirects.length > 1) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`@docusaurus/plugin-client-redirects: multiple redirects are created with the same "from" pathname=${from}
|
||||
It is not possible to redirect the same pathname to multiple destinations:
|
||||
- ${groupedFromRedirects.map((r) => JSON.stringify(r)).join('\n- ')}
|
||||
`,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
redirects = uniqBy(redirects, (redirect) => redirect.fromRoutePath);
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
redirects = uniqBy(redirects, (redirect) => redirect.from);
|
||||
|
||||
// We don't want to override an already existing route with a redirect file!
|
||||
const redirectsOverridingExistingPath = redirects.filter((redirect) =>
|
||||
pluginContext.routesPaths.includes(redirect.fromRoutePath),
|
||||
pluginContext.routesPaths.includes(redirect.from),
|
||||
);
|
||||
if (redirectsOverridingExistingPath.length > 0) {
|
||||
console.error(
|
||||
|
@ -100,7 +100,7 @@ It is not possible to redirect the same pathname to multiple destinations:
|
|||
);
|
||||
}
|
||||
redirects = redirects.filter(
|
||||
(redirect) => !pluginContext.routesPaths.includes(redirect.fromRoutePath),
|
||||
(redirect) => !pluginContext.routesPaths.includes(redirect.from),
|
||||
);
|
||||
|
||||
return redirects;
|
||||
|
@ -131,11 +131,11 @@ function createRedirectsOptionRedirects(
|
|||
// For conveniency, user can use a string or a string[]
|
||||
function optionToRedirects(option: RedirectOption): RedirectMetadata[] {
|
||||
if (typeof option.from === 'string') {
|
||||
return [{fromRoutePath: option.from, toRoutePath: option.to}];
|
||||
return [{from: option.from, to: option.to}];
|
||||
} else {
|
||||
return option.from.map((fromRoutePath) => ({
|
||||
fromRoutePath,
|
||||
toRoutePath: option.to,
|
||||
return option.from.map((from) => ({
|
||||
from,
|
||||
to: option.to,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -149,19 +149,17 @@ function createCreateRedirectsOptionRedirects(
|
|||
createRedirects: PluginOptions['createRedirects'],
|
||||
): RedirectMetadata[] {
|
||||
function createPathRedirects(path: string): RedirectMetadata[] {
|
||||
const fromRoutePathsMixed: string | string[] = createRedirects
|
||||
const fromsMixed: string | string[] = createRedirects
|
||||
? createRedirects(path) || []
|
||||
: [];
|
||||
|
||||
const fromRoutePaths: string[] =
|
||||
typeof fromRoutePathsMixed === 'string'
|
||||
? [fromRoutePathsMixed]
|
||||
: fromRoutePathsMixed;
|
||||
const froms: string[] =
|
||||
typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed;
|
||||
|
||||
return fromRoutePaths.map((fromRoutePath) => {
|
||||
return froms.map((from) => {
|
||||
return {
|
||||
fromRoutePath,
|
||||
toRoutePath: path,
|
||||
from,
|
||||
to: path,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ export function createToExtensionsRedirects(
|
|||
if (extensionFound) {
|
||||
const routePathWithoutExtension = removeSuffix(path, extensionFound);
|
||||
return [routePathWithoutExtension].map((from) => ({
|
||||
fromRoutePath: from,
|
||||
toRoutePath: path,
|
||||
from: from,
|
||||
to: path,
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
|
@ -80,8 +80,8 @@ export function createFromExtensionsRedirects(
|
|||
return [];
|
||||
} else {
|
||||
return extensions.map((ext) => ({
|
||||
fromRoutePath: `${path}.${ext}`,
|
||||
toRoutePath: path,
|
||||
from: `${path}.${ext}`,
|
||||
to: path,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,8 +17,8 @@ export const PathnameValidator = Yup.string().test({
|
|||
});
|
||||
|
||||
const RedirectSchema = Yup.object<RedirectMetadata>({
|
||||
fromRoutePath: PathnameValidator.required(),
|
||||
toRoutePath: PathnameValidator.required(),
|
||||
from: PathnameValidator.required(),
|
||||
to: PathnameValidator.required(),
|
||||
});
|
||||
|
||||
export function validateRedirect(redirect: RedirectMetadata) {
|
||||
|
|
|
@ -36,9 +36,9 @@ export type PluginContext = Pick<
|
|||
};
|
||||
|
||||
// In-memory representation of redirects we want: easier to test
|
||||
// /!\ easy to be confused: "fromRoutePath" is the new page we should create,
|
||||
// that redirects to "toRoutePath" the existing Docusaurus page
|
||||
// /!\ easy to be confused: "from" is the new page we should create,
|
||||
// that redirects to "to": the existing Docusaurus page
|
||||
export type RedirectMetadata = {
|
||||
fromRoutePath: string;
|
||||
toRoutePath: string;
|
||||
from: string; // pathname
|
||||
to: string; // pathname
|
||||
};
|
||||
|
|
|
@ -38,12 +38,10 @@ export function toRedirectFilesMetadata(
|
|||
const createFileMetadata = (redirect: RedirectMetadata) => {
|
||||
const fileAbsolutePath = path.join(
|
||||
pluginContext.outDir,
|
||||
getFilePathForRoutePath(redirect.fromRoutePath),
|
||||
getFilePathForRoutePath(redirect.from),
|
||||
);
|
||||
const toUrl = addTrailingSlash(
|
||||
`${removeTrailingSlash(pluginContext.baseUrl)}${path.join(
|
||||
redirect.toRoutePath,
|
||||
)}`,
|
||||
`${removeTrailingSlash(pluginContext.baseUrl)}${path.join(redirect.to)}`,
|
||||
);
|
||||
const fileContent = createPageContentMemoized(toUrl);
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue