@docusaurus/plugin-client-redirects 2.0.0-beta.ff31de0ff → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/collectRedirects.d.ts +2 -2
- package/lib/collectRedirects.js +45 -47
- package/lib/createRedirectPageContent.d.ts +2 -4
- package/lib/createRedirectPageContent.js +2 -4
- package/lib/extensionRedirects.d.ts +11 -3
- package/lib/extensionRedirects.js +22 -17
- package/lib/index.d.ts +5 -3
- package/lib/index.js +11 -8
- package/lib/options.d.ts +35 -0
- package/lib/options.js +36 -0
- package/lib/redirectValidation.d.ts +2 -2
- package/lib/types.d.ts +14 -16
- package/lib/writeRedirectFiles.d.ts +5 -5
- package/lib/writeRedirectFiles.js +41 -14
- package/package.json +16 -13
- package/src/collectRedirects.ts +76 -83
- package/src/createRedirectPageContent.ts +8 -10
- package/src/deps.d.ts +16 -0
- package/src/extensionRedirects.ts +32 -25
- package/src/index.ts +21 -14
- package/src/options.ts +75 -0
- package/src/redirectValidation.ts +3 -3
- package/src/types.ts +16 -30
- package/src/writeRedirectFiles.ts +53 -25
- package/lib/.tsbuildinfo +0 -1970
- package/lib/normalizePluginOptions.d.ts +0 -9
- package/lib/normalizePluginOptions.js +0 -44
- package/src/__tests__/__snapshots__/collectRedirects.test.ts.snap +0 -27
- package/src/__tests__/__snapshots__/createRedirectPageContent.test.ts.snap +0 -29
- package/src/__tests__/__snapshots__/normalizePluginOptions.test.ts.snap +0 -35
- package/src/__tests__/__snapshots__/redirectValidation.test.ts.snap +0 -11
- package/src/__tests__/__snapshots__/writeRedirectFiles.test.ts.snap +0 -71
- package/src/__tests__/collectRedirects.test.ts +0 -255
- package/src/__tests__/createRedirectPageContent.test.ts +0 -26
- package/src/__tests__/extensionRedirects.test.ts +0 -109
- package/src/__tests__/normalizePluginOptions.test.ts +0 -76
- package/src/__tests__/redirectValidation.test.ts +0 -66
- package/src/__tests__/writeRedirectFiles.test.ts +0 -146
- package/src/normalizePluginOptions.ts +0 -55
- package/tsconfig.json +0 -10
|
@@ -7,15 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
import fs from 'fs-extra';
|
|
9
9
|
import path from 'path';
|
|
10
|
-
import
|
|
10
|
+
import _ from 'lodash';
|
|
11
|
+
import logger from '@docusaurus/logger';
|
|
12
|
+
import {normalizeUrl} from '@docusaurus/utils';
|
|
11
13
|
|
|
12
|
-
import {PluginContext, RedirectMetadata} from './types';
|
|
13
14
|
import createRedirectPageContent from './createRedirectPageContent';
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
import type {PluginContext, RedirectItem} from './types';
|
|
15
17
|
|
|
16
18
|
export type WriteFilesPluginContext = Pick<PluginContext, 'baseUrl' | 'outDir'>;
|
|
17
19
|
|
|
18
|
-
export type
|
|
20
|
+
export type RedirectFile = {
|
|
19
21
|
fileAbsolutePath: string;
|
|
20
22
|
fileContent: string;
|
|
21
23
|
};
|
|
@@ -24,22 +26,52 @@ export function createToUrl(baseUrl: string, to: string): string {
|
|
|
24
26
|
return normalizeUrl([baseUrl, to]);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
// Create redirect file path
|
|
30
|
+
// Make sure this path has lower precedence over the original file path when
|
|
31
|
+
// served by host providers!
|
|
32
|
+
// Otherwise it can produce infinite redirect loops!
|
|
33
|
+
//
|
|
34
|
+
// See https://github.com/facebook/docusaurus/issues/5055
|
|
35
|
+
// See https://github.com/facebook/docusaurus/pull/5085
|
|
36
|
+
// See https://github.com/facebook/docusaurus/pull/5102
|
|
37
|
+
function getRedirectFilePath(
|
|
38
|
+
fromPath: string,
|
|
39
|
+
trailingSlash: boolean | undefined, // Now unused, on purpose
|
|
40
|
+
): string {
|
|
41
|
+
const fileName = path.basename(fromPath);
|
|
42
|
+
const filePath = path.dirname(fromPath);
|
|
43
|
+
// Edge case for https://github.com/facebook/docusaurus/pull/5102
|
|
44
|
+
// If the redirect source path is /xyz, with file /xyz.html
|
|
45
|
+
// We can't write the redirect file at /xyz.html/index.html because for Unix
|
|
46
|
+
// FS, a file/folder can't have the same name "xyz.html"
|
|
47
|
+
// The only possible solution for a redirect file is thus /xyz.html.html (I
|
|
48
|
+
// know, looks suspicious)
|
|
49
|
+
if (trailingSlash === false && fileName.endsWith('.html')) {
|
|
50
|
+
return path.join(filePath, `${fileName}.html`);
|
|
51
|
+
}
|
|
52
|
+
// If the target path is /xyz, with file /xyz/index.html, we don't want the
|
|
53
|
+
// redirect file to be /xyz.html, otherwise it would be picked in priority and
|
|
54
|
+
// the redirect file would redirect to itself. We prefer the redirect file to
|
|
55
|
+
// be /xyz.html/index.html, served with lower priority for most static hosting
|
|
56
|
+
// tools
|
|
57
|
+
return path.join(filePath, `${fileName}/index.html`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function toRedirectFiles(
|
|
61
|
+
redirects: RedirectItem[],
|
|
29
62
|
pluginContext: WriteFilesPluginContext,
|
|
30
|
-
|
|
63
|
+
trailingSlash: boolean | undefined,
|
|
64
|
+
): RedirectFile[] {
|
|
31
65
|
// Perf: avoid rendering the template twice with the exact same "props"
|
|
32
66
|
// We might create multiple redirect pages for the same destination url
|
|
33
67
|
// note: the first fn arg is the cache key!
|
|
34
|
-
const createPageContentMemoized = memoize((toUrl: string) =>
|
|
35
|
-
|
|
36
|
-
|
|
68
|
+
const createPageContentMemoized = _.memoize((toUrl: string) =>
|
|
69
|
+
createRedirectPageContent({toUrl}),
|
|
70
|
+
);
|
|
37
71
|
|
|
38
|
-
const createFileMetadata = (redirect:
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
getFilePathForRoutePath(redirect.from),
|
|
42
|
-
);
|
|
72
|
+
const createFileMetadata = (redirect: RedirectItem) => {
|
|
73
|
+
const fileRelativePath = getRedirectFilePath(redirect.from, trailingSlash);
|
|
74
|
+
const fileAbsolutePath = path.join(pluginContext.outDir, fileRelativePath);
|
|
43
75
|
const toUrl = createToUrl(pluginContext.baseUrl, redirect.to);
|
|
44
76
|
const fileContent = createPageContentMemoized(toUrl);
|
|
45
77
|
return {
|
|
@@ -52,18 +84,15 @@ export function toRedirectFilesMetadata(
|
|
|
52
84
|
return redirects.map(createFileMetadata);
|
|
53
85
|
}
|
|
54
86
|
|
|
55
|
-
export async function writeRedirectFile(
|
|
56
|
-
file: RedirectFileMetadata,
|
|
57
|
-
): Promise<void> {
|
|
87
|
+
export async function writeRedirectFile(file: RedirectFile): Promise<void> {
|
|
58
88
|
try {
|
|
59
89
|
// User-friendly security to prevent file overrides
|
|
60
90
|
if (await fs.pathExists(file.fileAbsolutePath)) {
|
|
61
91
|
throw new Error(
|
|
62
|
-
'The redirect plugin is not supposed to override existing files',
|
|
92
|
+
'The redirect plugin is not supposed to override existing files.',
|
|
63
93
|
);
|
|
64
94
|
}
|
|
65
|
-
await fs.
|
|
66
|
-
await fs.writeFile(
|
|
95
|
+
await fs.outputFile(
|
|
67
96
|
file.fileAbsolutePath,
|
|
68
97
|
file.fileContent,
|
|
69
98
|
// Hard security to prevent file overrides
|
|
@@ -71,14 +100,13 @@ export async function writeRedirectFile(
|
|
|
71
100
|
{flag: 'wx'},
|
|
72
101
|
);
|
|
73
102
|
} catch (err) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
);
|
|
103
|
+
logger.error`Redirect file creation error for path=${file.fileAbsolutePath}.`;
|
|
104
|
+
throw err;
|
|
77
105
|
}
|
|
78
106
|
}
|
|
79
107
|
|
|
80
108
|
export default async function writeRedirectFiles(
|
|
81
|
-
redirectFiles:
|
|
109
|
+
redirectFiles: RedirectFile[],
|
|
82
110
|
): Promise<void> {
|
|
83
111
|
await Promise.all(redirectFiles.map(writeRedirectFile));
|
|
84
112
|
}
|