rename fromRoutePath/toRoutePath to simply from/to

This commit is contained in:
slorber 2020-06-04 14:31:26 +02:00
parent 06673ee8c3
commit 0ac5a66a1f
11 changed files with 103 additions and 107 deletions

View file

@ -14,7 +14,7 @@ Valid paths you can redirect to:
exports[`collectRedirects should throw if redirect creator creates array of array redirect 1`] = ` exports[`collectRedirects should throw if redirect creator creates array of array redirect 1`] = `
"Some created redirects are invalid: "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\\\\\\"\\" \\"\\\\\\"/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`] = ` exports[`collectRedirects should throw if redirect creator creates invalid redirects 1`] = `
"Some created redirects are invalid: "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 - {\\"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
- {\\"fromRoutePath\\":\\"//abc\\",\\"toRoutePath\\":\\"/\\"} => Validation error: fromRoutePath 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
- {\\"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\\":\\"/def?queryString=toto\\",\\"to\\":\\"/\\"} => Validation error: from is not a valid pathname. Pathname should start with / and not contain any domain or query string
" "
`; `;

View file

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // 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"`;

View file

@ -45,12 +45,12 @@ describe('collectRedirects', () => {
), ),
).toEqual([ ).toEqual([
{ {
fromRoutePath: '/somePath.html', from: '/somePath.html',
toRoutePath: '/somePath', to: '/somePath',
}, },
{ {
fromRoutePath: '/somePath.exe', from: '/somePath.exe',
toRoutePath: '/somePath', to: '/somePath',
}, },
]); ]);
}); });
@ -67,8 +67,8 @@ describe('collectRedirects', () => {
), ),
).toEqual([ ).toEqual([
{ {
fromRoutePath: '/otherPath', from: '/otherPath',
toRoutePath: '/otherPath.html', to: '/otherPath.html',
}, },
]); ]);
}); });
@ -94,16 +94,16 @@ describe('collectRedirects', () => {
), ),
).toEqual([ ).toEqual([
{ {
fromRoutePath: '/someLegacyPath', from: '/someLegacyPath',
toRoutePath: '/somePath', to: '/somePath',
}, },
{ {
fromRoutePath: '/someLegacyPathArray1', from: '/someLegacyPathArray1',
toRoutePath: '/', to: '/',
}, },
{ {
fromRoutePath: '/someLegacyPathArray2', from: '/someLegacyPathArray2',
toRoutePath: '/', to: '/',
}, },
]); ]);
}); });
@ -151,30 +151,30 @@ describe('collectRedirects', () => {
), ),
).toEqual([ ).toEqual([
{ {
fromRoutePath: '/some/path/suffix1', from: '/some/path/suffix1',
toRoutePath: '/', to: '/',
}, },
{ {
fromRoutePath: '/some/other/path/suffix2', from: '/some/other/path/suffix2',
toRoutePath: '/', to: '/',
}, },
{ {
fromRoutePath: '/testpath/some/path/suffix1', from: '/testpath/some/path/suffix1',
toRoutePath: '/testpath', to: '/testpath',
}, },
{ {
fromRoutePath: '/testpath/some/other/path/suffix2', from: '/testpath/some/other/path/suffix2',
toRoutePath: '/testpath', to: '/testpath',
}, },
{ {
fromRoutePath: '/otherPath.html/some/path/suffix1', from: '/otherPath.html/some/path/suffix1',
toRoutePath: '/otherPath.html', to: '/otherPath.html',
}, },
{ {
fromRoutePath: '/otherPath.html/some/other/path/suffix2', from: '/otherPath.html/some/other/path/suffix2',
toRoutePath: '/otherPath.html', to: '/otherPath.html',
}, },
]); ]);
}); });
@ -239,16 +239,16 @@ describe('collectRedirects', () => {
), ),
).toEqual([ ).toEqual([
{ {
fromRoutePath: '/toShouldWork.html', from: '/toShouldWork.html',
toRoutePath: '/toShouldWork', to: '/toShouldWork',
}, },
{ {
fromRoutePath: '/toShouldWork.exe', from: '/toShouldWork.exe',
toRoutePath: '/toShouldWork', to: '/toShouldWork',
}, },
{ {
fromRoutePath: '/fromShouldWork', from: '/fromShouldWork',
toRoutePath: '/fromShouldWork.html', to: '/fromShouldWork.html',
}, },
]); ]);
}); });

View file

@ -55,10 +55,10 @@ describe('createToExtensionsRedirects', () => {
expect(createToExtensionsRedirects([''], ext)).toEqual([]); expect(createToExtensionsRedirects([''], ext)).toEqual([]);
expect(createToExtensionsRedirects(['/'], ext)).toEqual([]); expect(createToExtensionsRedirects(['/'], ext)).toEqual([]);
expect(createToExtensionsRedirects(['/abc.html'], ext)).toEqual([ expect(createToExtensionsRedirects(['/abc.html'], ext)).toEqual([
{fromRoutePath: '/abc', toRoutePath: '/abc.html'}, {from: '/abc', to: '/abc.html'},
]); ]);
expect(createToExtensionsRedirects(['/abc.htm'], ext)).toEqual([ expect(createToExtensionsRedirects(['/abc.htm'], ext)).toEqual([
{fromRoutePath: '/abc', toRoutePath: '/abc.htm'}, {from: '/abc', to: '/abc.htm'},
]); ]);
expect(createToExtensionsRedirects(['/abc.xyz'], ext)).toEqual([]); expect(createToExtensionsRedirects(['/abc.xyz'], ext)).toEqual([]);
}); });
@ -79,8 +79,8 @@ describe('createFromExtensionsRedirects', () => {
expect(createFromExtensionsRedirects([''], ext)).toEqual([]); expect(createFromExtensionsRedirects([''], ext)).toEqual([]);
expect(createFromExtensionsRedirects(['/'], ext)).toEqual([]); expect(createFromExtensionsRedirects(['/'], ext)).toEqual([]);
expect(createFromExtensionsRedirects(['/abc'], ext)).toEqual([ expect(createFromExtensionsRedirects(['/abc'], ext)).toEqual([
{fromRoutePath: '/abc.html', toRoutePath: '/abc'}, {from: '/abc.html', to: '/abc'},
{fromRoutePath: '/abc.htm', toRoutePath: '/abc'}, {from: '/abc.htm', to: '/abc'},
]); ]);
expect(createFromExtensionsRedirects(['/def.html'], ext)).toEqual([]); expect(createFromExtensionsRedirects(['/def.html'], ext)).toEqual([]);
expect(createFromExtensionsRedirects(['/def/'], ext)).toEqual([]); expect(createFromExtensionsRedirects(['/def/'], ext)).toEqual([]);

View file

@ -10,56 +10,56 @@ import {validateRedirect} from '../redirectValidation';
describe('validateRedirect', () => { describe('validateRedirect', () => {
test('validate good redirects without throwing', () => { test('validate good redirects without throwing', () => {
validateRedirect({ validateRedirect({
fromRoutePath: '/fromSomePath', from: '/fromSomePath',
toRoutePath: '/toSomePath', to: '/toSomePath',
}); });
validateRedirect({ validateRedirect({
fromRoutePath: '/from/Some/Path', from: '/from/Some/Path',
toRoutePath: '/toSomePath', to: '/toSomePath',
}); });
validateRedirect({ validateRedirect({
fromRoutePath: '/fromSomePath', from: '/fromSomePath',
toRoutePath: '/toSomePath', to: '/toSomePath',
}); });
validateRedirect({ validateRedirect({
fromRoutePath: '/fromSomePath', from: '/fromSomePath',
toRoutePath: '/to/Some/Path', to: '/to/Some/Path',
}); });
}); });
test('throw for bad redirects', () => { test('throw for bad redirects', () => {
expect(() => expect(() =>
validateRedirect({ validateRedirect({
fromRoutePath: 'https://fb.com/fromSomePath', from: 'https://fb.com/fromSomePath',
toRoutePath: '/toSomePath', to: '/toSomePath',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
expect(() => expect(() =>
validateRedirect({ validateRedirect({
fromRoutePath: '/fromSomePath', from: '/fromSomePath',
toRoutePath: 'https://fb.com/toSomePath', to: 'https://fb.com/toSomePath',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
expect(() => expect(() =>
validateRedirect({ validateRedirect({
fromRoutePath: '/fromSomePath', from: '/fromSomePath',
toRoutePath: '/toSomePath?queryString=xyz', to: '/toSomePath?queryString=xyz',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
expect(() => expect(() =>
validateRedirect({ validateRedirect({
fromRoutePath: null as any, from: null as any,
toRoutePath: '/toSomePath?queryString=xyz', to: '/toSomePath?queryString=xyz',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
expect(() => expect(() =>
validateRedirect({ validateRedirect({
fromRoutePath: ['heyho'] as any, from: ['heyho'] as any,
toRoutePath: '/toSomePath?queryString=xyz', to: '/toSomePath?queryString=xyz',
}), }),
).toThrowErrorMatchingSnapshot(); ).toThrowErrorMatchingSnapshot();
}); });

View file

@ -20,9 +20,9 @@ describe('toRedirectFilesMetadata', () => {
const redirectFiles = toRedirectFilesMetadata( const redirectFiles = toRedirectFilesMetadata(
[ [
{fromRoutePath: '/abc.html', toRoutePath: '/abc'}, {from: '/abc.html', to: '/abc'},
{fromRoutePath: '/def', toRoutePath: '/def.html'}, {from: '/def', to: '/def.html'},
{fromRoutePath: '/xyz', toRoutePath: '/'}, {from: '/xyz', to: '/'},
], ],
pluginContext, pluginContext,
); );
@ -44,7 +44,7 @@ describe('toRedirectFilesMetadata', () => {
baseUrl: '/', baseUrl: '/',
}; };
const redirectFiles = toRedirectFilesMetadata( const redirectFiles = toRedirectFilesMetadata(
[{fromRoutePath: '/abc.html', toRoutePath: '/abc'}], [{from: '/abc.html', to: '/abc'}],
pluginContext, pluginContext,
); );
expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot( expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot(
@ -58,7 +58,7 @@ describe('toRedirectFilesMetadata', () => {
baseUrl: '', baseUrl: '',
}; };
const redirectFiles = toRedirectFilesMetadata( const redirectFiles = toRedirectFilesMetadata(
[{fromRoutePath: '/abc.html', toRoutePath: '/abc'}], [{from: '/abc.html', to: '/abc'}],
pluginContext, pluginContext,
); );
expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot( expect(redirectFiles.map((f) => f.fileContent)).toMatchSnapshot(

View file

@ -50,7 +50,7 @@ function validateCollectedRedirects(
} }
const allowedToPaths = pluginContext.routesPaths; const allowedToPaths = pluginContext.routesPaths;
const toPaths = redirects.map((redirect) => redirect.toRoutePath); const toPaths = redirects.map((redirect) => redirect.to);
const illegalToPaths = difference(toPaths, allowedToPaths); const illegalToPaths = difference(toPaths, allowedToPaths);
if (illegalToPaths.length > 0) { if (illegalToPaths.length > 0) {
throw new Error( throw new Error(
@ -70,9 +70,8 @@ function filterUnwantedRedirects(
): RedirectMetadata[] { ): RedirectMetadata[] {
// we don't want to create twice the same redirect // we don't want to create twice the same redirect
// that would lead to writing twice the same html redirection file // that would lead to writing twice the same html redirection file
Object.entries( Object.entries(groupBy(redirects, (redirect) => redirect.from)).forEach(
groupBy(redirects, (redirect) => redirect.fromRoutePath), ([from, groupedFromRedirects]) => {
).forEach(([from, groupedFromRedirects]) => {
if (groupedFromRedirects.length > 1) { if (groupedFromRedirects.length > 1) {
console.error( console.error(
chalk.red( chalk.red(
@ -83,12 +82,13 @@ It is not possible to redirect the same pathname to multiple destinations:
), ),
); );
} }
}); },
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! // We don't want to override an already existing route with a redirect file!
const redirectsOverridingExistingPath = redirects.filter((redirect) => const redirectsOverridingExistingPath = redirects.filter((redirect) =>
pluginContext.routesPaths.includes(redirect.fromRoutePath), pluginContext.routesPaths.includes(redirect.from),
); );
if (redirectsOverridingExistingPath.length > 0) { if (redirectsOverridingExistingPath.length > 0) {
console.error( console.error(
@ -100,7 +100,7 @@ It is not possible to redirect the same pathname to multiple destinations:
); );
} }
redirects = redirects.filter( redirects = redirects.filter(
(redirect) => !pluginContext.routesPaths.includes(redirect.fromRoutePath), (redirect) => !pluginContext.routesPaths.includes(redirect.from),
); );
return redirects; return redirects;
@ -131,11 +131,11 @@ function createRedirectsOptionRedirects(
// For conveniency, user can use a string or a string[] // For conveniency, user can use a string or a string[]
function optionToRedirects(option: RedirectOption): RedirectMetadata[] { function optionToRedirects(option: RedirectOption): RedirectMetadata[] {
if (typeof option.from === 'string') { if (typeof option.from === 'string') {
return [{fromRoutePath: option.from, toRoutePath: option.to}]; return [{from: option.from, to: option.to}];
} else { } else {
return option.from.map((fromRoutePath) => ({ return option.from.map((from) => ({
fromRoutePath, from,
toRoutePath: option.to, to: option.to,
})); }));
} }
} }
@ -149,19 +149,17 @@ function createCreateRedirectsOptionRedirects(
createRedirects: PluginOptions['createRedirects'], createRedirects: PluginOptions['createRedirects'],
): RedirectMetadata[] { ): RedirectMetadata[] {
function createPathRedirects(path: string): RedirectMetadata[] { function createPathRedirects(path: string): RedirectMetadata[] {
const fromRoutePathsMixed: string | string[] = createRedirects const fromsMixed: string | string[] = createRedirects
? createRedirects(path) || [] ? createRedirects(path) || []
: []; : [];
const fromRoutePaths: string[] = const froms: string[] =
typeof fromRoutePathsMixed === 'string' typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed;
? [fromRoutePathsMixed]
: fromRoutePathsMixed;
return fromRoutePaths.map((fromRoutePath) => { return froms.map((from) => {
return { return {
fromRoutePath, from,
toRoutePath: path, to: path,
}; };
}); });
} }

View file

@ -53,8 +53,8 @@ export function createToExtensionsRedirects(
if (extensionFound) { if (extensionFound) {
const routePathWithoutExtension = removeSuffix(path, extensionFound); const routePathWithoutExtension = removeSuffix(path, extensionFound);
return [routePathWithoutExtension].map((from) => ({ return [routePathWithoutExtension].map((from) => ({
fromRoutePath: from, from: from,
toRoutePath: path, to: path,
})); }));
} }
return []; return [];
@ -80,8 +80,8 @@ export function createFromExtensionsRedirects(
return []; return [];
} else { } else {
return extensions.map((ext) => ({ return extensions.map((ext) => ({
fromRoutePath: `${path}.${ext}`, from: `${path}.${ext}`,
toRoutePath: path, to: path,
})); }));
} }
}; };

View file

@ -17,8 +17,8 @@ export const PathnameValidator = Yup.string().test({
}); });
const RedirectSchema = Yup.object<RedirectMetadata>({ const RedirectSchema = Yup.object<RedirectMetadata>({
fromRoutePath: PathnameValidator.required(), from: PathnameValidator.required(),
toRoutePath: PathnameValidator.required(), to: PathnameValidator.required(),
}); });
export function validateRedirect(redirect: RedirectMetadata) { export function validateRedirect(redirect: RedirectMetadata) {

View file

@ -36,9 +36,9 @@ export type PluginContext = Pick<
}; };
// In-memory representation of redirects we want: easier to test // In-memory representation of redirects we want: easier to test
// /!\ easy to be confused: "fromRoutePath" is the new page we should create, // /!\ easy to be confused: "from" is the new page we should create,
// that redirects to "toRoutePath" the existing Docusaurus page // that redirects to "to": the existing Docusaurus page
export type RedirectMetadata = { export type RedirectMetadata = {
fromRoutePath: string; from: string; // pathname
toRoutePath: string; to: string; // pathname
}; };

View file

@ -38,12 +38,10 @@ export function toRedirectFilesMetadata(
const createFileMetadata = (redirect: RedirectMetadata) => { const createFileMetadata = (redirect: RedirectMetadata) => {
const fileAbsolutePath = path.join( const fileAbsolutePath = path.join(
pluginContext.outDir, pluginContext.outDir,
getFilePathForRoutePath(redirect.fromRoutePath), getFilePathForRoutePath(redirect.from),
); );
const toUrl = addTrailingSlash( const toUrl = addTrailingSlash(
`${removeTrailingSlash(pluginContext.baseUrl)}${path.join( `${removeTrailingSlash(pluginContext.baseUrl)}${path.join(redirect.to)}`,
redirect.toRoutePath,
)}`,
); );
const fileContent = createPageContentMemoized(toUrl); const fileContent = createPageContentMemoized(toUrl);
return { return {