@docusaurus/plugin-client-redirects 2.0.0-beta.16 → 2.0.0-beta.19
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.js +5 -7
- package/lib/createRedirectPageContent.d.ts +2 -4
- package/lib/createRedirectPageContent.js +3 -3
- package/lib/index.d.ts +4 -2
- package/lib/index.js +6 -5
- package/lib/options.d.ts +31 -0
- package/lib/options.js +36 -0
- package/lib/types.d.ts +11 -1
- package/lib/writeRedirectFiles.js +5 -6
- package/package.json +11 -11
- package/src/collectRedirects.ts +4 -9
- package/src/createRedirectPageContent.ts +4 -6
- package/src/index.ts +7 -7
- package/src/options.ts +71 -0
- package/src/types.ts +13 -7
- package/src/writeRedirectFiles.ts +1 -2
- package/lib/normalizePluginOptions.d.ts +0 -9
- package/lib/normalizePluginOptions.js +0 -44
- package/src/normalizePluginOptions.ts +0 -59
- package/src/plugin-client-redirects.d.ts +0 -27
package/lib/collectRedirects.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
const tslib_1 = require("tslib");
|
|
10
|
-
const lodash_1 =
|
|
10
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
11
11
|
const extensionRedirects_1 = require("./extensionRedirects");
|
|
12
12
|
const redirectValidation_1 = require("./redirectValidation");
|
|
13
13
|
const utils_common_1 = require("@docusaurus/utils-common");
|
|
14
|
-
const logger_1 =
|
|
14
|
+
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
15
15
|
function collectRedirects(pluginContext, trailingSlash) {
|
|
16
16
|
let redirects = doCollectRedirects(pluginContext);
|
|
17
17
|
redirects = applyRedirectsTrailingSlash(redirects, {
|
|
@@ -65,8 +65,8 @@ Valid paths you can redirect to:
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
function filterUnwantedRedirects(redirects, pluginContext) {
|
|
68
|
-
//
|
|
69
|
-
//
|
|
68
|
+
// We don't want to create the same redirect twice, since that would lead to
|
|
69
|
+
// writing the same html redirection file twice.
|
|
70
70
|
Object.entries(lodash_1.default.groupBy(redirects, (redirect) => redirect.from)).forEach(([from, groupedFromRedirects]) => {
|
|
71
71
|
if (groupedFromRedirects.length > 1) {
|
|
72
72
|
logger_1.default.error `name=${'@docusaurus/plugin-client-redirects'}: multiple redirects are created with the same "from" pathname: path=${from}
|
|
@@ -106,9 +106,7 @@ function createRedirectsOptionRedirects(redirectsOption) {
|
|
|
106
106
|
// Create redirects from the "createRedirects" fn provided by the user
|
|
107
107
|
function createCreateRedirectsOptionRedirects(paths, createRedirects) {
|
|
108
108
|
function createPathRedirects(path) {
|
|
109
|
-
const fromsMixed = createRedirects
|
|
110
|
-
? createRedirects(path) || []
|
|
111
|
-
: [];
|
|
109
|
+
const fromsMixed = createRedirects?.(path) ?? [];
|
|
112
110
|
const froms = typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed;
|
|
113
111
|
return froms.map((from) => ({
|
|
114
112
|
from,
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
export default function createRedirectPageContent({ toUrl, }: {
|
|
8
8
|
toUrl: string;
|
|
9
|
-
};
|
|
10
|
-
export default function createRedirectPageContent({ toUrl, }: CreateRedirectPageOptions): string;
|
|
11
|
-
export {};
|
|
9
|
+
}): string;
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
const tslib_1 = require("tslib");
|
|
10
|
-
const eta =
|
|
11
|
-
const redirectPage_template_html_1 =
|
|
12
|
-
const lodash_1 =
|
|
10
|
+
const eta = tslib_1.__importStar(require("eta"));
|
|
11
|
+
const redirectPage_template_html_1 = tslib_1.__importDefault(require("./templates/redirectPage.template.html"));
|
|
12
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
13
13
|
const getCompiledRedirectPageTemplate = lodash_1.default.memoize(() => eta.compile(redirectPage_template_html_1.default.trim()));
|
|
14
14
|
function renderRedirectPageTemplate(data) {
|
|
15
15
|
const compiled = getCompiledRedirectPageTemplate();
|
package/lib/index.d.ts
CHANGED
|
@@ -5,5 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type { LoadContext, Plugin } from '@docusaurus/types';
|
|
8
|
-
import type { PluginOptions } from '
|
|
9
|
-
export default function pluginClientRedirectsPages(context: LoadContext,
|
|
8
|
+
import type { PluginOptions, Options } from './options';
|
|
9
|
+
export default function pluginClientRedirectsPages(context: LoadContext, options: PluginOptions): Plugin<unknown>;
|
|
10
|
+
export { validateOptions } from './options';
|
|
11
|
+
export type { PluginOptions, Options };
|
package/lib/index.js
CHANGED
|
@@ -6,14 +6,13 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.validateOptions = void 0;
|
|
9
10
|
const tslib_1 = require("tslib");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const writeRedirectFiles_1 = (0, tslib_1.__importStar)(require("./writeRedirectFiles"));
|
|
11
|
+
const collectRedirects_1 = tslib_1.__importDefault(require("./collectRedirects"));
|
|
12
|
+
const writeRedirectFiles_1 = tslib_1.__importStar(require("./writeRedirectFiles"));
|
|
13
13
|
const utils_1 = require("@docusaurus/utils");
|
|
14
|
-
function pluginClientRedirectsPages(context,
|
|
14
|
+
function pluginClientRedirectsPages(context, options) {
|
|
15
15
|
const { trailingSlash } = context.siteConfig;
|
|
16
|
-
const options = (0, normalizePluginOptions_1.default)(opts);
|
|
17
16
|
return {
|
|
18
17
|
name: 'docusaurus-plugin-client-redirects',
|
|
19
18
|
async postBuild(props) {
|
|
@@ -31,3 +30,5 @@ function pluginClientRedirectsPages(context, opts) {
|
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
32
|
exports.default = pluginClientRedirectsPages;
|
|
33
|
+
var options_1 = require("./options");
|
|
34
|
+
Object.defineProperty(exports, "validateOptions", { enumerable: true, get: function () { return options_1.validateOptions; } });
|
package/lib/options.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import type { OptionValidationContext } from '@docusaurus/types';
|
|
8
|
+
export declare type RedirectOption = {
|
|
9
|
+
to: string;
|
|
10
|
+
from: string | string[];
|
|
11
|
+
};
|
|
12
|
+
export declare type PluginOptions = {
|
|
13
|
+
/** Plugin ID. */
|
|
14
|
+
id: string;
|
|
15
|
+
/** The extensions to be removed from the route after redirecting. */
|
|
16
|
+
fromExtensions: string[];
|
|
17
|
+
/** The extensions to be appended to the route after redirecting. */
|
|
18
|
+
toExtensions: string[];
|
|
19
|
+
/** The list of redirect rules, each one with multiple `from`s → one `to`. */
|
|
20
|
+
redirects: RedirectOption[];
|
|
21
|
+
/**
|
|
22
|
+
* A callback to create a redirect rule.
|
|
23
|
+
* @returns All the paths from which we should redirect to `path`
|
|
24
|
+
*/
|
|
25
|
+
createRedirects?: (
|
|
26
|
+
/** An existing Docusaurus route path */
|
|
27
|
+
path: string) => string[] | string | null | undefined;
|
|
28
|
+
};
|
|
29
|
+
export declare type Options = Partial<PluginOptions>;
|
|
30
|
+
export declare const DEFAULT_OPTIONS: Partial<PluginOptions>;
|
|
31
|
+
export declare function validateOptions({ validate, options: userOptions, }: OptionValidationContext<Options, PluginOptions>): PluginOptions;
|
package/lib/options.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.validateOptions = exports.DEFAULT_OPTIONS = void 0;
|
|
10
|
+
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
11
|
+
exports.DEFAULT_OPTIONS = {
|
|
12
|
+
fromExtensions: [],
|
|
13
|
+
toExtensions: [],
|
|
14
|
+
redirects: [],
|
|
15
|
+
};
|
|
16
|
+
const RedirectPluginOptionValidation = utils_validation_1.Joi.object({
|
|
17
|
+
to: utils_validation_1.PathnameSchema.required(),
|
|
18
|
+
from: utils_validation_1.Joi.alternatives().try(utils_validation_1.PathnameSchema.required(), utils_validation_1.Joi.array().items(utils_validation_1.PathnameSchema.required())),
|
|
19
|
+
});
|
|
20
|
+
const isString = utils_validation_1.Joi.string().required().not(null);
|
|
21
|
+
const UserOptionsSchema = utils_validation_1.Joi.object({
|
|
22
|
+
fromExtensions: utils_validation_1.Joi.array()
|
|
23
|
+
.items(isString)
|
|
24
|
+
.default(exports.DEFAULT_OPTIONS.fromExtensions),
|
|
25
|
+
toExtensions: utils_validation_1.Joi.array()
|
|
26
|
+
.items(isString)
|
|
27
|
+
.default(exports.DEFAULT_OPTIONS.toExtensions),
|
|
28
|
+
redirects: utils_validation_1.Joi.array()
|
|
29
|
+
.items(RedirectPluginOptionValidation)
|
|
30
|
+
.default(exports.DEFAULT_OPTIONS.redirects),
|
|
31
|
+
createRedirects: utils_validation_1.Joi.function().maxArity(1),
|
|
32
|
+
}).default(exports.DEFAULT_OPTIONS);
|
|
33
|
+
function validateOptions({ validate, options: userOptions, }) {
|
|
34
|
+
return validate(UserOptionsSchema, userOptions);
|
|
35
|
+
}
|
|
36
|
+
exports.validateOptions = validateOptions;
|
package/lib/types.d.ts
CHANGED
|
@@ -5,12 +5,22 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type { Props } from '@docusaurus/types';
|
|
8
|
-
import type { PluginOptions } from '
|
|
8
|
+
import type { PluginOptions } from './options';
|
|
9
|
+
/**
|
|
10
|
+
* The minimal infos the plugin needs to work
|
|
11
|
+
*/
|
|
9
12
|
export declare type PluginContext = Pick<Props, 'outDir' | 'baseUrl'> & {
|
|
10
13
|
options: PluginOptions;
|
|
11
14
|
relativeRoutesPaths: string[];
|
|
12
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* In-memory representation of redirects we want: easier to test
|
|
18
|
+
* /!\ easy to be confused: "from" is the new page we should create,
|
|
19
|
+
* that redirects to "to": the existing Docusaurus page
|
|
20
|
+
*/
|
|
13
21
|
export declare type RedirectMetadata = {
|
|
22
|
+
/** Pathname of the new page we should create */
|
|
14
23
|
from: string;
|
|
24
|
+
/** Pathname of an existing Docusaurus page */
|
|
15
25
|
to: string;
|
|
16
26
|
};
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.writeRedirectFile = exports.toRedirectFilesMetadata = exports.createToUrl = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
|
-
const fs_extra_1 =
|
|
12
|
-
const path_1 =
|
|
13
|
-
const lodash_1 =
|
|
14
|
-
const createRedirectPageContent_1 =
|
|
11
|
+
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
12
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
13
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
14
|
+
const createRedirectPageContent_1 = tslib_1.__importDefault(require("./createRedirectPageContent"));
|
|
15
15
|
const utils_1 = require("@docusaurus/utils");
|
|
16
16
|
function createToUrl(baseUrl, to) {
|
|
17
17
|
return (0, utils_1.normalizeUrl)([baseUrl, to]);
|
|
@@ -69,8 +69,7 @@ async function writeRedirectFile(file) {
|
|
|
69
69
|
if (await fs_extra_1.default.pathExists(file.fileAbsolutePath)) {
|
|
70
70
|
throw new Error('The redirect plugin is not supposed to override existing files.');
|
|
71
71
|
}
|
|
72
|
-
await fs_extra_1.default.
|
|
73
|
-
await fs_extra_1.default.writeFile(file.fileAbsolutePath, file.fileContent,
|
|
72
|
+
await fs_extra_1.default.outputFile(file.fileAbsolutePath, file.fileContent,
|
|
74
73
|
// Hard security to prevent file overrides
|
|
75
74
|
// See https://stackoverflow.com/a/34187712/82609
|
|
76
75
|
{ flag: 'wx' });
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-client-redirects",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.19",
|
|
4
4
|
"description": "Client redirects plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
-
"types": "
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"watch": "tsc --watch"
|
|
@@ -18,18 +18,18 @@
|
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@docusaurus/core": "2.0.0-beta.
|
|
22
|
-
"@docusaurus/logger": "2.0.0-beta.
|
|
23
|
-
"@docusaurus/utils": "2.0.0-beta.
|
|
24
|
-
"@docusaurus/utils-common": "2.0.0-beta.
|
|
25
|
-
"@docusaurus/utils-validation": "2.0.0-beta.
|
|
21
|
+
"@docusaurus/core": "2.0.0-beta.19",
|
|
22
|
+
"@docusaurus/logger": "2.0.0-beta.19",
|
|
23
|
+
"@docusaurus/utils": "2.0.0-beta.19",
|
|
24
|
+
"@docusaurus/utils-common": "2.0.0-beta.19",
|
|
25
|
+
"@docusaurus/utils-validation": "2.0.0-beta.19",
|
|
26
26
|
"eta": "^1.12.3",
|
|
27
|
-
"fs-extra": "^10.0
|
|
27
|
+
"fs-extra": "^10.1.0",
|
|
28
28
|
"lodash": "^4.17.21",
|
|
29
|
-
"tslib": "^2.
|
|
29
|
+
"tslib": "^2.4.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@docusaurus/types": "2.0.0-beta.
|
|
32
|
+
"@docusaurus/types": "2.0.0-beta.19"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^16.8.4 || ^17.0.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=14"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "a71e60a49cce93c1006ef10c41ac03187f057102"
|
|
42
42
|
}
|
package/src/collectRedirects.ts
CHANGED
|
@@ -6,10 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import _ from 'lodash';
|
|
9
|
-
import type {
|
|
10
|
-
PluginOptions,
|
|
11
|
-
RedirectOption,
|
|
12
|
-
} from '@docusaurus/plugin-client-redirects';
|
|
9
|
+
import type {PluginOptions, RedirectOption} from './options';
|
|
13
10
|
import type {PluginContext, RedirectMetadata} from './types';
|
|
14
11
|
import {
|
|
15
12
|
createFromExtensionsRedirects,
|
|
@@ -96,8 +93,8 @@ function filterUnwantedRedirects(
|
|
|
96
93
|
redirects: RedirectMetadata[],
|
|
97
94
|
pluginContext: PluginContext,
|
|
98
95
|
): RedirectMetadata[] {
|
|
99
|
-
//
|
|
100
|
-
//
|
|
96
|
+
// We don't want to create the same redirect twice, since that would lead to
|
|
97
|
+
// writing the same html redirection file twice.
|
|
101
98
|
Object.entries(_.groupBy(redirects, (redirect) => redirect.from)).forEach(
|
|
102
99
|
([from, groupedFromRedirects]) => {
|
|
103
100
|
if (groupedFromRedirects.length > 1) {
|
|
@@ -166,9 +163,7 @@ function createCreateRedirectsOptionRedirects(
|
|
|
166
163
|
createRedirects: PluginOptions['createRedirects'],
|
|
167
164
|
): RedirectMetadata[] {
|
|
168
165
|
function createPathRedirects(path: string): RedirectMetadata[] {
|
|
169
|
-
const fromsMixed: string | string[] = createRedirects
|
|
170
|
-
? createRedirects(path) || []
|
|
171
|
-
: [];
|
|
166
|
+
const fromsMixed: string | string[] = createRedirects?.(path) ?? [];
|
|
172
167
|
|
|
173
168
|
const froms: string[] =
|
|
174
169
|
typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed;
|
|
@@ -9,22 +9,20 @@ import * as eta from 'eta';
|
|
|
9
9
|
import redirectPageTemplate from './templates/redirectPage.template.html';
|
|
10
10
|
import _ from 'lodash';
|
|
11
11
|
|
|
12
|
-
type CreateRedirectPageOptions = {
|
|
13
|
-
toUrl: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
12
|
const getCompiledRedirectPageTemplate = _.memoize(() =>
|
|
17
13
|
eta.compile(redirectPageTemplate.trim()),
|
|
18
14
|
);
|
|
19
15
|
|
|
20
|
-
function renderRedirectPageTemplate(data:
|
|
16
|
+
function renderRedirectPageTemplate(data: {toUrl: string}) {
|
|
21
17
|
const compiled = getCompiledRedirectPageTemplate();
|
|
22
18
|
return compiled(data, eta.defaultConfig);
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
export default function createRedirectPageContent({
|
|
26
22
|
toUrl,
|
|
27
|
-
}:
|
|
23
|
+
}: {
|
|
24
|
+
toUrl: string;
|
|
25
|
+
}): string {
|
|
28
26
|
return renderRedirectPageTemplate({
|
|
29
27
|
toUrl: encodeURI(toUrl),
|
|
30
28
|
});
|
package/src/index.ts
CHANGED
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {LoadContext, Plugin
|
|
8
|
+
import type {LoadContext, Plugin} from '@docusaurus/types';
|
|
9
9
|
import type {PluginContext, RedirectMetadata} from './types';
|
|
10
|
-
import type {PluginOptions} from '
|
|
10
|
+
import type {PluginOptions, Options} from './options';
|
|
11
11
|
|
|
12
|
-
import normalizePluginOptions from './normalizePluginOptions';
|
|
13
12
|
import collectRedirects from './collectRedirects';
|
|
14
13
|
import writeRedirectFiles, {
|
|
15
14
|
toRedirectFilesMetadata,
|
|
@@ -19,15 +18,13 @@ import {removePrefix, addLeadingSlash} from '@docusaurus/utils';
|
|
|
19
18
|
|
|
20
19
|
export default function pluginClientRedirectsPages(
|
|
21
20
|
context: LoadContext,
|
|
22
|
-
|
|
21
|
+
options: PluginOptions,
|
|
23
22
|
): Plugin<unknown> {
|
|
24
23
|
const {trailingSlash} = context.siteConfig;
|
|
25
24
|
|
|
26
|
-
const options = normalizePluginOptions(opts);
|
|
27
|
-
|
|
28
25
|
return {
|
|
29
26
|
name: 'docusaurus-plugin-client-redirects',
|
|
30
|
-
async postBuild(props
|
|
27
|
+
async postBuild(props) {
|
|
31
28
|
const pluginContext: PluginContext = {
|
|
32
29
|
relativeRoutesPaths: props.routesPaths.map(
|
|
33
30
|
(path) => `${addLeadingSlash(removePrefix(path, props.baseUrl))}`,
|
|
@@ -53,3 +50,6 @@ export default function pluginClientRedirectsPages(
|
|
|
53
50
|
},
|
|
54
51
|
};
|
|
55
52
|
}
|
|
53
|
+
|
|
54
|
+
export {validateOptions} from './options';
|
|
55
|
+
export type {PluginOptions, Options};
|
package/src/options.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {OptionValidationContext} from '@docusaurus/types';
|
|
9
|
+
import {Joi, PathnameSchema} from '@docusaurus/utils-validation';
|
|
10
|
+
|
|
11
|
+
export type RedirectOption = {
|
|
12
|
+
to: string;
|
|
13
|
+
from: string | string[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type PluginOptions = {
|
|
17
|
+
/** Plugin ID. */
|
|
18
|
+
id: string;
|
|
19
|
+
/** The extensions to be removed from the route after redirecting. */
|
|
20
|
+
fromExtensions: string[];
|
|
21
|
+
/** The extensions to be appended to the route after redirecting. */
|
|
22
|
+
toExtensions: string[];
|
|
23
|
+
/** The list of redirect rules, each one with multiple `from`s → one `to`. */
|
|
24
|
+
redirects: RedirectOption[];
|
|
25
|
+
/**
|
|
26
|
+
* A callback to create a redirect rule.
|
|
27
|
+
* @returns All the paths from which we should redirect to `path`
|
|
28
|
+
*/
|
|
29
|
+
createRedirects?: (
|
|
30
|
+
/** An existing Docusaurus route path */
|
|
31
|
+
path: string,
|
|
32
|
+
) => string[] | string | null | undefined;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type Options = Partial<PluginOptions>;
|
|
36
|
+
|
|
37
|
+
export const DEFAULT_OPTIONS: Partial<PluginOptions> = {
|
|
38
|
+
fromExtensions: [],
|
|
39
|
+
toExtensions: [],
|
|
40
|
+
redirects: [],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const RedirectPluginOptionValidation = Joi.object<RedirectOption>({
|
|
44
|
+
to: PathnameSchema.required(),
|
|
45
|
+
from: Joi.alternatives().try(
|
|
46
|
+
PathnameSchema.required(),
|
|
47
|
+
Joi.array().items(PathnameSchema.required()),
|
|
48
|
+
),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const isString = Joi.string().required().not(null);
|
|
52
|
+
|
|
53
|
+
const UserOptionsSchema = Joi.object<PluginOptions>({
|
|
54
|
+
fromExtensions: Joi.array()
|
|
55
|
+
.items(isString)
|
|
56
|
+
.default(DEFAULT_OPTIONS.fromExtensions),
|
|
57
|
+
toExtensions: Joi.array()
|
|
58
|
+
.items(isString)
|
|
59
|
+
.default(DEFAULT_OPTIONS.toExtensions),
|
|
60
|
+
redirects: Joi.array()
|
|
61
|
+
.items(RedirectPluginOptionValidation)
|
|
62
|
+
.default(DEFAULT_OPTIONS.redirects),
|
|
63
|
+
createRedirects: Joi.function().maxArity(1),
|
|
64
|
+
}).default(DEFAULT_OPTIONS);
|
|
65
|
+
|
|
66
|
+
export function validateOptions({
|
|
67
|
+
validate,
|
|
68
|
+
options: userOptions,
|
|
69
|
+
}: OptionValidationContext<Options, PluginOptions>): PluginOptions {
|
|
70
|
+
return validate(UserOptionsSchema, userOptions);
|
|
71
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -6,18 +6,24 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type {Props} from '@docusaurus/types';
|
|
9
|
-
import type {PluginOptions} from '
|
|
9
|
+
import type {PluginOptions} from './options';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The minimal infos the plugin needs to work
|
|
13
|
+
*/
|
|
12
14
|
export type PluginContext = Pick<Props, 'outDir' | 'baseUrl'> & {
|
|
13
15
|
options: PluginOptions;
|
|
14
16
|
relativeRoutesPaths: string[];
|
|
15
17
|
};
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* In-memory representation of redirects we want: easier to test
|
|
21
|
+
* /!\ easy to be confused: "from" is the new page we should create,
|
|
22
|
+
* that redirects to "to": the existing Docusaurus page
|
|
23
|
+
*/
|
|
20
24
|
export type RedirectMetadata = {
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
/** Pathname of the new page we should create */
|
|
26
|
+
from: string;
|
|
27
|
+
/** Pathname of an existing Docusaurus page */
|
|
28
|
+
to: string;
|
|
23
29
|
};
|
|
@@ -92,8 +92,7 @@ export async function writeRedirectFile(
|
|
|
92
92
|
'The redirect plugin is not supposed to override existing files.',
|
|
93
93
|
);
|
|
94
94
|
}
|
|
95
|
-
await fs.
|
|
96
|
-
await fs.writeFile(
|
|
95
|
+
await fs.outputFile(
|
|
97
96
|
file.fileAbsolutePath,
|
|
98
97
|
file.fileContent,
|
|
99
98
|
// Hard security to prevent file overrides
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
import type { PluginOptions, Options as UserPluginOptions } from '@docusaurus/plugin-client-redirects';
|
|
8
|
-
export declare const DefaultPluginOptions: PluginOptions;
|
|
9
|
-
export default function normalizePluginOptions(userPluginOptions?: UserPluginOptions): PluginOptions;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.DefaultPluginOptions = void 0;
|
|
10
|
-
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
11
|
-
const utils_1 = require("@docusaurus/utils");
|
|
12
|
-
exports.DefaultPluginOptions = {
|
|
13
|
-
id: utils_1.DEFAULT_PLUGIN_ID,
|
|
14
|
-
fromExtensions: [],
|
|
15
|
-
toExtensions: [],
|
|
16
|
-
redirects: [],
|
|
17
|
-
};
|
|
18
|
-
const RedirectPluginOptionValidation = utils_validation_1.Joi.object({
|
|
19
|
-
to: utils_validation_1.PathnameSchema.required(),
|
|
20
|
-
from: utils_validation_1.Joi.alternatives().try(utils_validation_1.PathnameSchema.required(), utils_validation_1.Joi.array().items(utils_validation_1.PathnameSchema.required())),
|
|
21
|
-
});
|
|
22
|
-
const isString = utils_validation_1.Joi.string().required().not(null);
|
|
23
|
-
const UserOptionsSchema = utils_validation_1.Joi.object({
|
|
24
|
-
id: utils_validation_1.Joi.string().optional(),
|
|
25
|
-
fromExtensions: utils_validation_1.Joi.array().items(isString),
|
|
26
|
-
toExtensions: utils_validation_1.Joi.array().items(isString),
|
|
27
|
-
redirects: utils_validation_1.Joi.array().items(RedirectPluginOptionValidation),
|
|
28
|
-
createRedirects: utils_validation_1.Joi.function().arity(1),
|
|
29
|
-
});
|
|
30
|
-
function validateUserOptions(userOptions) {
|
|
31
|
-
const { error } = UserOptionsSchema.validate(userOptions, {
|
|
32
|
-
abortEarly: true,
|
|
33
|
-
allowUnknown: false,
|
|
34
|
-
});
|
|
35
|
-
if (error) {
|
|
36
|
-
throw new Error(`Invalid @docusaurus/plugin-client-redirects options: ${error.message}
|
|
37
|
-
${JSON.stringify(userOptions, null, 2)}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function normalizePluginOptions(userPluginOptions = {}) {
|
|
41
|
-
validateUserOptions(userPluginOptions);
|
|
42
|
-
return { ...exports.DefaultPluginOptions, ...userPluginOptions };
|
|
43
|
-
}
|
|
44
|
-
exports.default = normalizePluginOptions;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
PluginOptions,
|
|
10
|
-
Options as UserPluginOptions,
|
|
11
|
-
RedirectOption,
|
|
12
|
-
} from '@docusaurus/plugin-client-redirects';
|
|
13
|
-
import {Joi, PathnameSchema} from '@docusaurus/utils-validation';
|
|
14
|
-
import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
|
|
15
|
-
|
|
16
|
-
export const DefaultPluginOptions: PluginOptions = {
|
|
17
|
-
id: DEFAULT_PLUGIN_ID, // TODO temporary
|
|
18
|
-
fromExtensions: [],
|
|
19
|
-
toExtensions: [],
|
|
20
|
-
redirects: [],
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const RedirectPluginOptionValidation = Joi.object<RedirectOption>({
|
|
24
|
-
to: PathnameSchema.required(),
|
|
25
|
-
from: Joi.alternatives().try(
|
|
26
|
-
PathnameSchema.required(),
|
|
27
|
-
Joi.array().items(PathnameSchema.required()),
|
|
28
|
-
),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const isString = Joi.string().required().not(null);
|
|
32
|
-
|
|
33
|
-
const UserOptionsSchema = Joi.object<UserPluginOptions>({
|
|
34
|
-
id: Joi.string().optional(), // TODO remove once validation migrated to new system
|
|
35
|
-
fromExtensions: Joi.array().items(isString),
|
|
36
|
-
toExtensions: Joi.array().items(isString),
|
|
37
|
-
redirects: Joi.array().items(RedirectPluginOptionValidation),
|
|
38
|
-
createRedirects: Joi.function().arity(1),
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
function validateUserOptions(userOptions: UserPluginOptions) {
|
|
42
|
-
const {error} = UserOptionsSchema.validate(userOptions, {
|
|
43
|
-
abortEarly: true,
|
|
44
|
-
allowUnknown: false,
|
|
45
|
-
});
|
|
46
|
-
if (error) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`Invalid @docusaurus/plugin-client-redirects options: ${error.message}
|
|
49
|
-
${JSON.stringify(userOptions, null, 2)}`,
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default function normalizePluginOptions(
|
|
55
|
-
userPluginOptions: UserPluginOptions = {},
|
|
56
|
-
): PluginOptions {
|
|
57
|
-
validateUserOptions(userPluginOptions);
|
|
58
|
-
return {...DefaultPluginOptions, ...userPluginOptions};
|
|
59
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export type RedirectOption = {
|
|
9
|
-
to: string;
|
|
10
|
-
from: string | string[];
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// For a given existing route path,
|
|
14
|
-
// return all the paths from which we should redirect from
|
|
15
|
-
export type CreateRedirectsFnOption = (
|
|
16
|
-
path: string,
|
|
17
|
-
) => string[] | string | null | undefined;
|
|
18
|
-
|
|
19
|
-
export type PluginOptions = {
|
|
20
|
-
id: string;
|
|
21
|
-
fromExtensions: string[];
|
|
22
|
-
toExtensions: string[];
|
|
23
|
-
redirects: RedirectOption[];
|
|
24
|
-
createRedirects?: CreateRedirectsFnOption;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export type Options = Partial<PluginOptions>;
|