@docusaurus/plugin-content-docs 0.0.0-4357 → 0.0.0-4365
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/categoryGeneratedIndex.js +2 -0
- package/lib/globalData.d.ts +3 -1
- package/lib/globalData.js +23 -1
- package/lib/index.js +1 -1
- package/lib/routes.js +3 -1
- package/lib/sidebars/types.d.ts +4 -0
- package/lib/sidebars/utils.d.ts +9 -0
- package/lib/sidebars/utils.js +37 -0
- package/lib/sidebars/validation.js +2 -0
- package/lib/types.d.ts +10 -0
- package/lib/versions.d.ts +1 -1
- package/lib/versions.js +27 -32
- package/package.json +9 -9
- package/src/categoryGeneratedIndex.ts +2 -0
- package/src/globalData.ts +31 -0
- package/src/index.ts +1 -1
- package/src/plugin-content-docs.d.ts +4 -1
- package/src/routes.ts +13 -2
- package/src/sidebars/types.ts +4 -0
- package/src/sidebars/utils.ts +57 -0
- package/src/sidebars/validation.ts +2 -0
- package/src/types.ts +13 -0
- package/src/versions.ts +44 -40
|
@@ -18,6 +18,8 @@ function getCategoryGeneratedIndexMetadata({ category, sidebarsUtils, docsById,
|
|
|
18
18
|
return {
|
|
19
19
|
title: (_a = category.link.title) !== null && _a !== void 0 ? _a : category.label,
|
|
20
20
|
description: category.link.description,
|
|
21
|
+
image: category.link.image,
|
|
22
|
+
keywords: category.link.keywords,
|
|
21
23
|
slug: category.link.slug,
|
|
22
24
|
permalink: category.link.permalink,
|
|
23
25
|
sidebar: sidebarName,
|
package/lib/globalData.d.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
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
|
-
import type {
|
|
7
|
+
import type { Sidebars } from './sidebars/types';
|
|
8
|
+
import type { DocMetadata, GlobalDoc, LoadedVersion, GlobalVersion, GlobalSidebar } from './types';
|
|
8
9
|
export declare function toGlobalDataDoc(doc: DocMetadata): GlobalDoc;
|
|
10
|
+
export declare function toGlobalSidebars(sidebars: Sidebars, version: LoadedVersion): Record<string, GlobalSidebar>;
|
|
9
11
|
export declare function toGlobalDataVersion(version: LoadedVersion): GlobalVersion;
|
package/lib/globalData.js
CHANGED
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.toGlobalDataVersion = exports.toGlobalDataDoc = void 0;
|
|
9
|
+
exports.toGlobalDataVersion = exports.toGlobalSidebars = exports.toGlobalDataDoc = void 0;
|
|
10
|
+
const lodash_1 = require("lodash");
|
|
11
|
+
const utils_1 = require("@docusaurus/utils");
|
|
12
|
+
const utils_2 = require("./sidebars/utils");
|
|
10
13
|
function toGlobalDataDoc(doc) {
|
|
11
14
|
return {
|
|
12
15
|
id: doc.unversionedId,
|
|
@@ -15,6 +18,24 @@ function toGlobalDataDoc(doc) {
|
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
20
|
exports.toGlobalDataDoc = toGlobalDataDoc;
|
|
21
|
+
function toGlobalSidebars(sidebars, version) {
|
|
22
|
+
const { getFirstLink } = (0, utils_2.createSidebarsUtils)(sidebars);
|
|
23
|
+
return (0, lodash_1.mapValues)(sidebars, (sidebar, sidebarId) => {
|
|
24
|
+
const firstLink = getFirstLink(sidebarId);
|
|
25
|
+
if (!firstLink) {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
link: {
|
|
30
|
+
path: firstLink.type === 'generated-index'
|
|
31
|
+
? (0, utils_1.normalizeUrl)([version.versionPath, firstLink.slug])
|
|
32
|
+
: version.docs.find((doc) => doc.id === firstLink.id || doc.unversionedId === firstLink.id).permalink,
|
|
33
|
+
label: firstLink.label,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exports.toGlobalSidebars = toGlobalSidebars;
|
|
18
39
|
function toGlobalDataVersion(version) {
|
|
19
40
|
return {
|
|
20
41
|
name: version.versionName,
|
|
@@ -23,6 +44,7 @@ function toGlobalDataVersion(version) {
|
|
|
23
44
|
path: version.versionPath,
|
|
24
45
|
mainDocId: version.mainDocId,
|
|
25
46
|
docs: version.docs.map(toGlobalDataDoc),
|
|
47
|
+
sidebars: toGlobalSidebars(version.sidebars, version),
|
|
26
48
|
};
|
|
27
49
|
}
|
|
28
50
|
exports.toGlobalDataVersion = toGlobalDataVersion;
|
package/lib/index.js
CHANGED
|
@@ -28,7 +28,7 @@ const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
|
|
|
28
28
|
async function pluginContentDocs(context, options) {
|
|
29
29
|
var _a;
|
|
30
30
|
const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
|
|
31
|
-
const versionsMetadata = (0, versions_1.readVersionsMetadata)({ context, options });
|
|
31
|
+
const versionsMetadata = await (0, versions_1.readVersionsMetadata)({ context, options });
|
|
32
32
|
const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : utils_1.DEFAULT_PLUGIN_ID;
|
|
33
33
|
const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-docs');
|
|
34
34
|
const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
|
package/lib/routes.js
CHANGED
|
@@ -14,13 +14,15 @@ const logger_1 = (0, tslib_1.__importDefault)(require("@docusaurus/logger"));
|
|
|
14
14
|
async function createCategoryGeneratedIndexRoutes({ version, actions, docCategoryGeneratedIndexComponent, }) {
|
|
15
15
|
const slugs = (0, utils_1.createSlugger)();
|
|
16
16
|
async function createCategoryGeneratedIndexRoute(categoryGeneratedIndex) {
|
|
17
|
-
const { sidebar, title, description, slug, permalink, previous, next } = categoryGeneratedIndex;
|
|
17
|
+
const { sidebar, title, description, slug, permalink, previous, next, image, keywords, } = categoryGeneratedIndex;
|
|
18
18
|
const propFileName = slugs.slug(`${version.versionPath}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`);
|
|
19
19
|
const prop = {
|
|
20
20
|
title,
|
|
21
21
|
description,
|
|
22
22
|
slug,
|
|
23
23
|
permalink,
|
|
24
|
+
image,
|
|
25
|
+
keywords,
|
|
24
26
|
navigation: {
|
|
25
27
|
previous,
|
|
26
28
|
next,
|
package/lib/sidebars/types.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export declare type SidebarItemCategoryLinkGeneratedIndexConfig = {
|
|
|
42
42
|
slug?: string;
|
|
43
43
|
title?: string;
|
|
44
44
|
description?: string;
|
|
45
|
+
image?: string;
|
|
46
|
+
keywords?: string | readonly string[];
|
|
45
47
|
};
|
|
46
48
|
export declare type SidebarItemCategoryLinkGeneratedIndex = {
|
|
47
49
|
type: 'generated-index';
|
|
@@ -49,6 +51,8 @@ export declare type SidebarItemCategoryLinkGeneratedIndex = {
|
|
|
49
51
|
permalink: string;
|
|
50
52
|
title?: string;
|
|
51
53
|
description?: string;
|
|
54
|
+
image?: string;
|
|
55
|
+
keywords?: string | readonly string[];
|
|
52
56
|
};
|
|
53
57
|
export declare type SidebarItemCategoryLinkConfig = SidebarItemCategoryLinkDoc | SidebarItemCategoryLinkGeneratedIndexConfig;
|
|
54
58
|
export declare type SidebarItemCategoryLink = SidebarItemCategoryLinkDoc | SidebarItemCategoryLinkGeneratedIndex;
|
package/lib/sidebars/utils.d.ts
CHANGED
|
@@ -27,6 +27,15 @@ export declare type SidebarsUtils = {
|
|
|
27
27
|
getDocNavigation: (unversionedId: string, versionedId: string) => SidebarNavigation;
|
|
28
28
|
getCategoryGeneratedIndexList: () => SidebarItemCategoryWithGeneratedIndex[];
|
|
29
29
|
getCategoryGeneratedIndexNavigation: (categoryGeneratedIndexPermalink: string) => SidebarNavigation;
|
|
30
|
+
getFirstLink: (sidebarId: string) => {
|
|
31
|
+
type: 'doc';
|
|
32
|
+
id: string;
|
|
33
|
+
label: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'generated-index';
|
|
36
|
+
slug: string;
|
|
37
|
+
label: string;
|
|
38
|
+
} | undefined;
|
|
30
39
|
checkSidebarsDocIds: (validDocIds: string[], sidebarFilePath: string) => void;
|
|
31
40
|
};
|
|
32
41
|
export declare function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils;
|
package/lib/sidebars/utils.js
CHANGED
|
@@ -173,6 +173,42 @@ Available document ids are:
|
|
|
173
173
|
- ${(0, lodash_1.uniq)(validDocIds).sort().join('\n- ')}`);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
+
function getFirstLink(sidebar) {
|
|
177
|
+
var _a, _b, _c;
|
|
178
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
179
|
+
for (const item of sidebar) {
|
|
180
|
+
if (item.type === 'doc') {
|
|
181
|
+
return {
|
|
182
|
+
type: 'doc',
|
|
183
|
+
id: item.id,
|
|
184
|
+
label: (_a = item.label) !== null && _a !== void 0 ? _a : item.id,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
else if (item.type === 'category') {
|
|
188
|
+
if (((_b = item.link) === null || _b === void 0 ? void 0 : _b.type) === 'doc') {
|
|
189
|
+
return {
|
|
190
|
+
type: 'doc',
|
|
191
|
+
id: item.link.id,
|
|
192
|
+
label: item.label,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
else if (((_c = item.link) === null || _c === void 0 ? void 0 : _c.type) === 'generated-index') {
|
|
196
|
+
return {
|
|
197
|
+
type: 'generated-index',
|
|
198
|
+
slug: item.link.slug,
|
|
199
|
+
label: item.label,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const firstSubItem = getFirstLink(item.items);
|
|
204
|
+
if (firstSubItem) {
|
|
205
|
+
return firstSubItem;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
176
212
|
return {
|
|
177
213
|
sidebars,
|
|
178
214
|
getFirstDocIdOfFirstSidebar,
|
|
@@ -181,6 +217,7 @@ Available document ids are:
|
|
|
181
217
|
getCategoryGeneratedIndexList,
|
|
182
218
|
getCategoryGeneratedIndexNavigation,
|
|
183
219
|
checkSidebarsDocIds,
|
|
220
|
+
getFirstLink: (id) => getFirstLink(sidebars[id]),
|
|
184
221
|
};
|
|
185
222
|
}
|
|
186
223
|
exports.createSidebarsUtils = createSidebarsUtils;
|
|
@@ -50,6 +50,8 @@ const sidebarItemCategoryLinkSchema = utils_validation_1.Joi.object()
|
|
|
50
50
|
// permalink: Joi.string().optional(), // No, this one is not in the user config, only in the normalized version
|
|
51
51
|
title: utils_validation_1.Joi.string().optional(),
|
|
52
52
|
description: utils_validation_1.Joi.string().optional(),
|
|
53
|
+
image: utils_validation_1.Joi.string().optional(),
|
|
54
|
+
keywords: [utils_validation_1.Joi.string(), utils_validation_1.Joi.array().items(utils_validation_1.Joi.string())],
|
|
53
55
|
}),
|
|
54
56
|
},
|
|
55
57
|
{
|
package/lib/types.d.ts
CHANGED
|
@@ -144,6 +144,8 @@ export declare type CategoryGeneratedIndexMetadata = {
|
|
|
144
144
|
sidebar: string;
|
|
145
145
|
previous?: DocNavLink;
|
|
146
146
|
next?: DocNavLink;
|
|
147
|
+
image?: string;
|
|
148
|
+
keywords?: string | readonly string[];
|
|
147
149
|
};
|
|
148
150
|
export declare type SourceToPermalink = {
|
|
149
151
|
[source: string]: string;
|
|
@@ -178,6 +180,14 @@ export declare type GlobalVersion = {
|
|
|
178
180
|
path: string;
|
|
179
181
|
mainDocId: string;
|
|
180
182
|
docs: GlobalDoc[];
|
|
183
|
+
sidebars?: Record<string, GlobalSidebar>;
|
|
184
|
+
};
|
|
185
|
+
export declare type GlobalSidebarLink = {
|
|
186
|
+
label: string;
|
|
187
|
+
path: string;
|
|
188
|
+
};
|
|
189
|
+
export declare type GlobalSidebar = {
|
|
190
|
+
link?: GlobalSidebarLink;
|
|
181
191
|
};
|
|
182
192
|
export declare type GlobalPluginData = {
|
|
183
193
|
path: string;
|
package/lib/versions.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export declare function getVersionsFilePath(siteDir: string, pluginId: string):
|
|
|
12
12
|
export declare function readVersionsMetadata({ context, options, }: {
|
|
13
13
|
context: Pick<LoadContext, 'siteDir' | 'baseUrl' | 'i18n'>;
|
|
14
14
|
options: Pick<PluginOptions, 'id' | 'path' | 'sidebarPath' | 'routeBasePath' | 'tagsBasePath' | 'includeCurrentVersion' | 'disableVersioning' | 'lastVersion' | 'versions' | 'onlyIncludeVersions' | 'editUrl' | 'editCurrentVersion'>;
|
|
15
|
-
}): VersionMetadata[]
|
|
15
|
+
}): Promise<VersionMetadata[]>;
|
|
16
16
|
export declare function getDocsDirPaths(versionMetadata: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'>): [string, string];
|
package/lib/versions.js
CHANGED
|
@@ -50,11 +50,10 @@ function ensureValidVersionArray(versionArray) {
|
|
|
50
50
|
}
|
|
51
51
|
versionArray.forEach(ensureValidVersionString);
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
function readVersionsFile(siteDir, pluginId) {
|
|
53
|
+
async function readVersionsFile(siteDir, pluginId) {
|
|
55
54
|
const versionsFilePath = getVersionsFilePath(siteDir, pluginId);
|
|
56
|
-
if (fs_extra_1.default.
|
|
57
|
-
const content = JSON.parse(fs_extra_1.default.
|
|
55
|
+
if (await fs_extra_1.default.pathExists(versionsFilePath)) {
|
|
56
|
+
const content = JSON.parse(await fs_extra_1.default.readFile(versionsFilePath, 'utf8'));
|
|
58
57
|
ensureValidVersionArray(content);
|
|
59
58
|
return content;
|
|
60
59
|
}
|
|
@@ -62,22 +61,21 @@ function readVersionsFile(siteDir, pluginId) {
|
|
|
62
61
|
return null;
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const versionFileContent = readVersionsFile(siteDir, options.id);
|
|
64
|
+
async function readVersionNames(siteDir, options) {
|
|
65
|
+
const versionFileContent = await readVersionsFile(siteDir, options.id);
|
|
68
66
|
if (!versionFileContent && options.disableVersioning) {
|
|
69
|
-
throw new Error(`Docs: using "disableVersioning
|
|
67
|
+
throw new Error(`Docs: using "disableVersioning: ${options.disableVersioning}" option on a non-versioned site does not make sense.`);
|
|
70
68
|
}
|
|
71
69
|
const versions = options.disableVersioning ? [] : versionFileContent !== null && versionFileContent !== void 0 ? versionFileContent : [];
|
|
72
|
-
// We add the current version at the beginning, unless
|
|
73
|
-
// - user don't want to
|
|
74
|
-
// - it's been explicitly added to versions.json
|
|
70
|
+
// We add the current version at the beginning, unless:
|
|
71
|
+
// - user don't want to; or
|
|
72
|
+
// - it's already been explicitly added to versions.json
|
|
75
73
|
if (options.includeCurrentVersion &&
|
|
76
74
|
!versions.includes(constants_1.CURRENT_VERSION_NAME)) {
|
|
77
75
|
versions.unshift(constants_1.CURRENT_VERSION_NAME);
|
|
78
76
|
}
|
|
79
77
|
if (versions.length === 0) {
|
|
80
|
-
throw new Error(`It is not possible to use docs without any version. Please check the configuration of these options: "includeCurrentVersion
|
|
78
|
+
throw new Error(`It is not possible to use docs without any version. Please check the configuration of these options: "includeCurrentVersion: ${options.includeCurrentVersion}", "disableVersioning: ${options.disableVersioning}".`);
|
|
81
79
|
}
|
|
82
80
|
return versions;
|
|
83
81
|
}
|
|
@@ -96,27 +94,23 @@ function getDocsDirPathLocalized({ siteDir, locale, pluginId, versionName, }) {
|
|
|
96
94
|
}
|
|
97
95
|
function getVersionMetadataPaths({ versionName, context, options, }) {
|
|
98
96
|
const isCurrentVersion = versionName === constants_1.CURRENT_VERSION_NAME;
|
|
99
|
-
const contentPath = isCurrentVersion
|
|
100
|
-
? path_1.default.resolve(context.siteDir, options.path)
|
|
101
|
-
: path_1.default.join(getVersionedDocsDirPath(context.siteDir, options.id), `version-${versionName}`);
|
|
102
97
|
const contentPathLocalized = getDocsDirPathLocalized({
|
|
103
98
|
siteDir: context.siteDir,
|
|
104
99
|
locale: context.i18n.currentLocale,
|
|
105
100
|
pluginId: options.id,
|
|
106
101
|
versionName,
|
|
107
102
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
103
|
+
if (isCurrentVersion) {
|
|
104
|
+
return {
|
|
105
|
+
contentPath: path_1.default.resolve(context.siteDir, options.path),
|
|
106
|
+
contentPathLocalized,
|
|
107
|
+
sidebarFilePath: (0, sidebars_1.resolveSidebarPathOption)(context.siteDir, options.sidebarPath),
|
|
108
|
+
};
|
|
115
109
|
}
|
|
116
110
|
return {
|
|
117
|
-
contentPath,
|
|
111
|
+
contentPath: path_1.default.join(getVersionedDocsDirPath(context.siteDir, options.id), `version-${versionName}`),
|
|
118
112
|
contentPathLocalized,
|
|
119
|
-
sidebarFilePath:
|
|
113
|
+
sidebarFilePath: path_1.default.join(getVersionedSidebarsDirPath(context.siteDir, options.id), `version-${versionName}-sidebars.json`),
|
|
120
114
|
};
|
|
121
115
|
}
|
|
122
116
|
function getVersionEditUrls({ contentPath, contentPathLocalized, context: { siteDir, i18n }, options: { id, path: currentVersionPath, editUrl, editCurrentVersion }, }) {
|
|
@@ -262,7 +256,7 @@ function checkVersionMetadataPaths({ versionMetadata, context, }) {
|
|
|
262
256
|
Please set the docs "sidebarPath" field in your config file to:
|
|
263
257
|
- a sidebars path that exists
|
|
264
258
|
- false: to disable the sidebar
|
|
265
|
-
- undefined: for Docusaurus
|
|
259
|
+
- undefined: for Docusaurus to generate it automatically`);
|
|
266
260
|
}
|
|
267
261
|
}
|
|
268
262
|
// TODO for retrocompatibility with existing behavior
|
|
@@ -280,7 +274,7 @@ function checkVersionsOptions(availableVersionNames, options) {
|
|
|
280
274
|
const availableVersionNamesMsg = `Available version names are: ${availableVersionNames.join(', ')}`;
|
|
281
275
|
if (options.lastVersion &&
|
|
282
276
|
!availableVersionNames.includes(options.lastVersion)) {
|
|
283
|
-
throw new Error(`Docs option lastVersion
|
|
277
|
+
throw new Error(`Docs option lastVersion: ${options.lastVersion} is invalid. ${availableVersionNamesMsg}`);
|
|
284
278
|
}
|
|
285
279
|
const unknownVersionConfigNames = (0, lodash_1.difference)(Object.keys(options.versions), availableVersionNames);
|
|
286
280
|
if (unknownVersionConfigNames.length > 0) {
|
|
@@ -300,9 +294,11 @@ function checkVersionsOptions(availableVersionNames, options) {
|
|
|
300
294
|
}
|
|
301
295
|
}
|
|
302
296
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Filter versions according to provided options.
|
|
299
|
+
* Note: we preserve the order in which versions are provided;
|
|
300
|
+
* the order of the onlyIncludeVersions array does not matter
|
|
301
|
+
*/
|
|
306
302
|
function filterVersions(versionNamesUnfiltered, options) {
|
|
307
303
|
if (options.onlyIncludeVersions) {
|
|
308
304
|
return versionNamesUnfiltered.filter((name) => (options.onlyIncludeVersions || []).includes(name));
|
|
@@ -311,10 +307,9 @@ function filterVersions(versionNamesUnfiltered, options) {
|
|
|
311
307
|
return versionNamesUnfiltered;
|
|
312
308
|
}
|
|
313
309
|
}
|
|
314
|
-
|
|
315
|
-
function readVersionsMetadata({ context, options, }) {
|
|
310
|
+
async function readVersionsMetadata({ context, options, }) {
|
|
316
311
|
var _a;
|
|
317
|
-
const versionNamesUnfiltered = readVersionNames(context.siteDir, options);
|
|
312
|
+
const versionNamesUnfiltered = await readVersionNames(context.siteDir, options);
|
|
318
313
|
checkVersionsOptions(versionNamesUnfiltered, options);
|
|
319
314
|
const versionNames = filterVersions(versionNamesUnfiltered, options);
|
|
320
315
|
const lastVersionName = (_a = options.lastVersion) !== null && _a !== void 0 ? _a : getDefaultLastVersionName(versionNames);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-content-docs",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-4365",
|
|
4
4
|
"description": "Docs plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/plugin-content-docs.d.ts",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@docusaurus/core": "0.0.0-
|
|
22
|
-
"@docusaurus/logger": "0.0.0-
|
|
23
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
24
|
-
"@docusaurus/utils": "0.0.0-
|
|
25
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
21
|
+
"@docusaurus/core": "0.0.0-4365",
|
|
22
|
+
"@docusaurus/logger": "0.0.0-4365",
|
|
23
|
+
"@docusaurus/mdx-loader": "0.0.0-4365",
|
|
24
|
+
"@docusaurus/utils": "0.0.0-4365",
|
|
25
|
+
"@docusaurus/utils-validation": "0.0.0-4365",
|
|
26
26
|
"combine-promises": "^1.1.0",
|
|
27
27
|
"escape-string-regexp": "^4.0.0",
|
|
28
28
|
"fs-extra": "^10.0.0",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"webpack": "^5.61.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
42
|
-
"@docusaurus/types": "0.0.0-
|
|
41
|
+
"@docusaurus/module-type-aliases": "0.0.0-4365",
|
|
42
|
+
"@docusaurus/types": "0.0.0-4365",
|
|
43
43
|
"@types/js-yaml": "^4.0.0",
|
|
44
44
|
"@types/picomatch": "^2.2.1",
|
|
45
45
|
"commander": "^5.1.0",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=14"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "c3975ea3f75f6f038c322fa23b6ffa2c46328007"
|
|
57
57
|
}
|
|
@@ -28,6 +28,8 @@ function getCategoryGeneratedIndexMetadata({
|
|
|
28
28
|
return {
|
|
29
29
|
title: category.link.title ?? category.label,
|
|
30
30
|
description: category.link.description,
|
|
31
|
+
image: category.link.image,
|
|
32
|
+
keywords: category.link.keywords,
|
|
31
33
|
slug: category.link.slug,
|
|
32
34
|
permalink: category.link.permalink,
|
|
33
35
|
sidebar: sidebarName,
|
package/src/globalData.ts
CHANGED
|
@@ -5,11 +5,16 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import {mapValues} from 'lodash';
|
|
9
|
+
import {normalizeUrl} from '@docusaurus/utils';
|
|
10
|
+
import type {Sidebars} from './sidebars/types';
|
|
11
|
+
import {createSidebarsUtils} from './sidebars/utils';
|
|
8
12
|
import type {
|
|
9
13
|
DocMetadata,
|
|
10
14
|
GlobalDoc,
|
|
11
15
|
LoadedVersion,
|
|
12
16
|
GlobalVersion,
|
|
17
|
+
GlobalSidebar,
|
|
13
18
|
} from './types';
|
|
14
19
|
|
|
15
20
|
export function toGlobalDataDoc(doc: DocMetadata): GlobalDoc {
|
|
@@ -20,6 +25,31 @@ export function toGlobalDataDoc(doc: DocMetadata): GlobalDoc {
|
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
27
|
|
|
28
|
+
export function toGlobalSidebars(
|
|
29
|
+
sidebars: Sidebars,
|
|
30
|
+
version: LoadedVersion,
|
|
31
|
+
): Record<string, GlobalSidebar> {
|
|
32
|
+
const {getFirstLink} = createSidebarsUtils(sidebars);
|
|
33
|
+
return mapValues(sidebars, (sidebar, sidebarId) => {
|
|
34
|
+
const firstLink = getFirstLink(sidebarId);
|
|
35
|
+
if (!firstLink) {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
link: {
|
|
40
|
+
path:
|
|
41
|
+
firstLink.type === 'generated-index'
|
|
42
|
+
? normalizeUrl([version.versionPath, firstLink.slug])
|
|
43
|
+
: version.docs.find(
|
|
44
|
+
(doc) =>
|
|
45
|
+
doc.id === firstLink.id || doc.unversionedId === firstLink.id,
|
|
46
|
+
)!.permalink,
|
|
47
|
+
label: firstLink.label,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
23
53
|
export function toGlobalDataVersion(version: LoadedVersion): GlobalVersion {
|
|
24
54
|
return {
|
|
25
55
|
name: version.versionName,
|
|
@@ -28,5 +58,6 @@ export function toGlobalDataVersion(version: LoadedVersion): GlobalVersion {
|
|
|
28
58
|
path: version.versionPath,
|
|
29
59
|
mainDocId: version.mainDocId,
|
|
30
60
|
docs: version.docs.map(toGlobalDataDoc),
|
|
61
|
+
sidebars: toGlobalSidebars(version.sidebars, version),
|
|
31
62
|
};
|
|
32
63
|
}
|
package/src/index.ts
CHANGED
|
@@ -64,7 +64,7 @@ export default async function pluginContentDocs(
|
|
|
64
64
|
): Promise<Plugin<LoadedContent>> {
|
|
65
65
|
const {siteDir, generatedFilesDir, baseUrl, siteConfig} = context;
|
|
66
66
|
|
|
67
|
-
const versionsMetadata = readVersionsMetadata({context, options});
|
|
67
|
+
const versionsMetadata = await readVersionsMetadata({context, options});
|
|
68
68
|
|
|
69
69
|
const pluginId = options.id ?? DEFAULT_PLUGIN_ID;
|
|
70
70
|
|
|
@@ -11,9 +11,10 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
11
11
|
export type VersionBanner = import('./types').VersionBanner;
|
|
12
12
|
type GlobalDataVersion = import('./types').GlobalVersion;
|
|
13
13
|
type GlobalDataDoc = import('./types').GlobalDoc;
|
|
14
|
+
type GlobalDataSidebar = import('./types').GlobalSidebar;
|
|
14
15
|
type VersionTag = import('./types').VersionTag;
|
|
15
16
|
|
|
16
|
-
export type {GlobalDataVersion, GlobalDataDoc};
|
|
17
|
+
export type {GlobalDataVersion, GlobalDataDoc, GlobalDataSidebar};
|
|
17
18
|
|
|
18
19
|
export type PropNavigationLink = {
|
|
19
20
|
readonly title: string;
|
|
@@ -42,6 +43,8 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
42
43
|
export type PropCategoryGeneratedIndex = {
|
|
43
44
|
title: string;
|
|
44
45
|
description?: string;
|
|
46
|
+
image?: string;
|
|
47
|
+
keywords?: string | readonly string[];
|
|
45
48
|
slug: string;
|
|
46
49
|
permalink: string;
|
|
47
50
|
navigation: PropNavigation;
|
package/src/routes.ts
CHANGED
|
@@ -30,8 +30,17 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
30
30
|
async function createCategoryGeneratedIndexRoute(
|
|
31
31
|
categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
|
|
32
32
|
): Promise<RouteConfig> {
|
|
33
|
-
const {
|
|
34
|
-
|
|
33
|
+
const {
|
|
34
|
+
sidebar,
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
slug,
|
|
38
|
+
permalink,
|
|
39
|
+
previous,
|
|
40
|
+
next,
|
|
41
|
+
image,
|
|
42
|
+
keywords,
|
|
43
|
+
} = categoryGeneratedIndex;
|
|
35
44
|
|
|
36
45
|
const propFileName = slugs.slug(
|
|
37
46
|
`${version.versionPath}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`,
|
|
@@ -42,6 +51,8 @@ export async function createCategoryGeneratedIndexRoutes({
|
|
|
42
51
|
description,
|
|
43
52
|
slug,
|
|
44
53
|
permalink,
|
|
54
|
+
image,
|
|
55
|
+
keywords,
|
|
45
56
|
navigation: {
|
|
46
57
|
previous,
|
|
47
58
|
next,
|
package/src/sidebars/types.ts
CHANGED
|
@@ -52,6 +52,8 @@ export type SidebarItemCategoryLinkGeneratedIndexConfig = {
|
|
|
52
52
|
slug?: string;
|
|
53
53
|
title?: string;
|
|
54
54
|
description?: string;
|
|
55
|
+
image?: string;
|
|
56
|
+
keywords?: string | readonly string[];
|
|
55
57
|
};
|
|
56
58
|
export type SidebarItemCategoryLinkGeneratedIndex = {
|
|
57
59
|
type: 'generated-index';
|
|
@@ -59,6 +61,8 @@ export type SidebarItemCategoryLinkGeneratedIndex = {
|
|
|
59
61
|
permalink: string;
|
|
60
62
|
title?: string;
|
|
61
63
|
description?: string;
|
|
64
|
+
image?: string;
|
|
65
|
+
keywords?: string | readonly string[];
|
|
62
66
|
};
|
|
63
67
|
|
|
64
68
|
export type SidebarItemCategoryLinkConfig =
|
package/src/sidebars/utils.ts
CHANGED
|
@@ -136,6 +136,18 @@ export type SidebarsUtils = {
|
|
|
136
136
|
getCategoryGeneratedIndexNavigation: (
|
|
137
137
|
categoryGeneratedIndexPermalink: string,
|
|
138
138
|
) => SidebarNavigation;
|
|
139
|
+
getFirstLink: (sidebarId: string) =>
|
|
140
|
+
| {
|
|
141
|
+
type: 'doc';
|
|
142
|
+
id: string;
|
|
143
|
+
label: string;
|
|
144
|
+
}
|
|
145
|
+
| {
|
|
146
|
+
type: 'generated-index';
|
|
147
|
+
slug: string;
|
|
148
|
+
label: string;
|
|
149
|
+
}
|
|
150
|
+
| undefined;
|
|
139
151
|
|
|
140
152
|
checkSidebarsDocIds: (validDocIds: string[], sidebarFilePath: string) => void;
|
|
141
153
|
};
|
|
@@ -264,6 +276,50 @@ Available document ids are:
|
|
|
264
276
|
}
|
|
265
277
|
}
|
|
266
278
|
|
|
279
|
+
function getFirstLink(sidebar: Sidebar):
|
|
280
|
+
| {
|
|
281
|
+
type: 'doc';
|
|
282
|
+
id: string;
|
|
283
|
+
label: string;
|
|
284
|
+
}
|
|
285
|
+
| {
|
|
286
|
+
type: 'generated-index';
|
|
287
|
+
slug: string;
|
|
288
|
+
label: string;
|
|
289
|
+
}
|
|
290
|
+
| undefined {
|
|
291
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
292
|
+
for (const item of sidebar) {
|
|
293
|
+
if (item.type === 'doc') {
|
|
294
|
+
return {
|
|
295
|
+
type: 'doc',
|
|
296
|
+
id: item.id,
|
|
297
|
+
label: item.label ?? item.id,
|
|
298
|
+
};
|
|
299
|
+
} else if (item.type === 'category') {
|
|
300
|
+
if (item.link?.type === 'doc') {
|
|
301
|
+
return {
|
|
302
|
+
type: 'doc',
|
|
303
|
+
id: item.link.id,
|
|
304
|
+
label: item.label,
|
|
305
|
+
};
|
|
306
|
+
} else if (item.link?.type === 'generated-index') {
|
|
307
|
+
return {
|
|
308
|
+
type: 'generated-index',
|
|
309
|
+
slug: item.link.slug,
|
|
310
|
+
label: item.label,
|
|
311
|
+
};
|
|
312
|
+
} else {
|
|
313
|
+
const firstSubItem = getFirstLink(item.items);
|
|
314
|
+
if (firstSubItem) {
|
|
315
|
+
return firstSubItem;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
|
|
267
323
|
return {
|
|
268
324
|
sidebars,
|
|
269
325
|
getFirstDocIdOfFirstSidebar,
|
|
@@ -272,6 +328,7 @@ Available document ids are:
|
|
|
272
328
|
getCategoryGeneratedIndexList,
|
|
273
329
|
getCategoryGeneratedIndexNavigation,
|
|
274
330
|
checkSidebarsDocIds,
|
|
331
|
+
getFirstLink: (id) => getFirstLink(sidebars[id]),
|
|
275
332
|
};
|
|
276
333
|
}
|
|
277
334
|
|
|
@@ -70,6 +70,8 @@ const sidebarItemCategoryLinkSchema = Joi.object<SidebarItemCategoryLink>()
|
|
|
70
70
|
// permalink: Joi.string().optional(), // No, this one is not in the user config, only in the normalized version
|
|
71
71
|
title: Joi.string().optional(),
|
|
72
72
|
description: Joi.string().optional(),
|
|
73
|
+
image: Joi.string().optional(),
|
|
74
|
+
keywords: [Joi.string(), Joi.array().items(Joi.string())],
|
|
73
75
|
}),
|
|
74
76
|
},
|
|
75
77
|
{
|
package/src/types.ts
CHANGED
|
@@ -174,6 +174,8 @@ export type CategoryGeneratedIndexMetadata = {
|
|
|
174
174
|
sidebar: string;
|
|
175
175
|
previous?: DocNavLink;
|
|
176
176
|
next?: DocNavLink;
|
|
177
|
+
image?: string;
|
|
178
|
+
keywords?: string | readonly string[];
|
|
177
179
|
};
|
|
178
180
|
|
|
179
181
|
export type SourceToPermalink = {
|
|
@@ -214,6 +216,17 @@ export type GlobalVersion = {
|
|
|
214
216
|
path: string;
|
|
215
217
|
mainDocId: string; // home doc (if docs homepage configured), or first doc
|
|
216
218
|
docs: GlobalDoc[];
|
|
219
|
+
sidebars?: Record<string, GlobalSidebar>;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
export type GlobalSidebarLink = {
|
|
223
|
+
label: string;
|
|
224
|
+
path: string;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export type GlobalSidebar = {
|
|
228
|
+
link?: GlobalSidebarLink;
|
|
229
|
+
// ... we may add other things here later
|
|
217
230
|
};
|
|
218
231
|
|
|
219
232
|
export type GlobalPluginData = {
|
package/src/versions.ts
CHANGED
|
@@ -87,11 +87,13 @@ function ensureValidVersionArray(
|
|
|
87
87
|
versionArray.forEach(ensureValidVersionString);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
async function readVersionsFile(
|
|
91
|
+
siteDir: string,
|
|
92
|
+
pluginId: string,
|
|
93
|
+
): Promise<string[] | null> {
|
|
92
94
|
const versionsFilePath = getVersionsFilePath(siteDir, pluginId);
|
|
93
|
-
if (fs.
|
|
94
|
-
const content = JSON.parse(fs.
|
|
95
|
+
if (await fs.pathExists(versionsFilePath)) {
|
|
96
|
+
const content = JSON.parse(await fs.readFile(versionsFilePath, 'utf8'));
|
|
95
97
|
ensureValidVersionArray(content);
|
|
96
98
|
return content;
|
|
97
99
|
} else {
|
|
@@ -99,27 +101,26 @@ function readVersionsFile(siteDir: string, pluginId: string): string[] | null {
|
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
function readVersionNames(
|
|
104
|
+
async function readVersionNames(
|
|
104
105
|
siteDir: string,
|
|
105
106
|
options: Pick<
|
|
106
107
|
PluginOptions,
|
|
107
108
|
'id' | 'disableVersioning' | 'includeCurrentVersion'
|
|
108
109
|
>,
|
|
109
|
-
): string[] {
|
|
110
|
-
const versionFileContent = readVersionsFile(siteDir, options.id);
|
|
110
|
+
): Promise<string[]> {
|
|
111
|
+
const versionFileContent = await readVersionsFile(siteDir, options.id);
|
|
111
112
|
|
|
112
113
|
if (!versionFileContent && options.disableVersioning) {
|
|
113
114
|
throw new Error(
|
|
114
|
-
`Docs: using "disableVersioning
|
|
115
|
+
`Docs: using "disableVersioning: ${options.disableVersioning}" option on a non-versioned site does not make sense.`,
|
|
115
116
|
);
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
const versions = options.disableVersioning ? [] : versionFileContent ?? [];
|
|
119
120
|
|
|
120
|
-
// We add the current version at the beginning, unless
|
|
121
|
-
// - user don't want to
|
|
122
|
-
// - it's been explicitly added to versions.json
|
|
121
|
+
// We add the current version at the beginning, unless:
|
|
122
|
+
// - user don't want to; or
|
|
123
|
+
// - it's already been explicitly added to versions.json
|
|
123
124
|
if (
|
|
124
125
|
options.includeCurrentVersion &&
|
|
125
126
|
!versions.includes(CURRENT_VERSION_NAME)
|
|
@@ -129,7 +130,7 @@ function readVersionNames(
|
|
|
129
130
|
|
|
130
131
|
if (versions.length === 0) {
|
|
131
132
|
throw new Error(
|
|
132
|
-
`It is not possible to use docs without any version. Please check the configuration of these options: "includeCurrentVersion
|
|
133
|
+
`It is not possible to use docs without any version. Please check the configuration of these options: "includeCurrentVersion: ${options.includeCurrentVersion}", "disableVersioning: ${options.disableVersioning}".`,
|
|
133
134
|
);
|
|
134
135
|
}
|
|
135
136
|
|
|
@@ -174,13 +175,6 @@ function getVersionMetadataPaths({
|
|
|
174
175
|
> {
|
|
175
176
|
const isCurrentVersion = versionName === CURRENT_VERSION_NAME;
|
|
176
177
|
|
|
177
|
-
const contentPath = isCurrentVersion
|
|
178
|
-
? path.resolve(context.siteDir, options.path)
|
|
179
|
-
: path.join(
|
|
180
|
-
getVersionedDocsDirPath(context.siteDir, options.id),
|
|
181
|
-
`version-${versionName}`,
|
|
182
|
-
);
|
|
183
|
-
|
|
184
178
|
const contentPathLocalized = getDocsDirPathLocalized({
|
|
185
179
|
siteDir: context.siteDir,
|
|
186
180
|
locale: context.i18n.currentLocale,
|
|
@@ -188,21 +182,27 @@ function getVersionMetadataPaths({
|
|
|
188
182
|
versionName,
|
|
189
183
|
});
|
|
190
184
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
)
|
|
199
|
-
}
|
|
185
|
+
if (isCurrentVersion) {
|
|
186
|
+
return {
|
|
187
|
+
contentPath: path.resolve(context.siteDir, options.path),
|
|
188
|
+
contentPathLocalized,
|
|
189
|
+
sidebarFilePath: resolveSidebarPathOption(
|
|
190
|
+
context.siteDir,
|
|
191
|
+
options.sidebarPath,
|
|
192
|
+
),
|
|
193
|
+
};
|
|
200
194
|
}
|
|
201
195
|
|
|
202
196
|
return {
|
|
203
|
-
contentPath
|
|
197
|
+
contentPath: path.join(
|
|
198
|
+
getVersionedDocsDirPath(context.siteDir, options.id),
|
|
199
|
+
`version-${versionName}`,
|
|
200
|
+
),
|
|
204
201
|
contentPathLocalized,
|
|
205
|
-
sidebarFilePath:
|
|
202
|
+
sidebarFilePath: path.join(
|
|
203
|
+
getVersionedSidebarsDirPath(context.siteDir, options.id),
|
|
204
|
+
`version-${versionName}-sidebars.json`,
|
|
205
|
+
),
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -459,7 +459,7 @@ function checkVersionMetadataPaths({
|
|
|
459
459
|
Please set the docs "sidebarPath" field in your config file to:
|
|
460
460
|
- a sidebars path that exists
|
|
461
461
|
- false: to disable the sidebar
|
|
462
|
-
- undefined: for Docusaurus
|
|
462
|
+
- undefined: for Docusaurus to generate it automatically`);
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
465
|
|
|
@@ -488,7 +488,7 @@ function checkVersionsOptions(
|
|
|
488
488
|
!availableVersionNames.includes(options.lastVersion)
|
|
489
489
|
) {
|
|
490
490
|
throw new Error(
|
|
491
|
-
`Docs option lastVersion
|
|
491
|
+
`Docs option lastVersion: ${options.lastVersion} is invalid. ${availableVersionNamesMsg}`,
|
|
492
492
|
);
|
|
493
493
|
}
|
|
494
494
|
const unknownVersionConfigNames = difference(
|
|
@@ -531,9 +531,11 @@ function checkVersionsOptions(
|
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
533
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
534
|
+
/**
|
|
535
|
+
* Filter versions according to provided options.
|
|
536
|
+
* Note: we preserve the order in which versions are provided;
|
|
537
|
+
* the order of the onlyIncludeVersions array does not matter
|
|
538
|
+
*/
|
|
537
539
|
function filterVersions(
|
|
538
540
|
versionNamesUnfiltered: string[],
|
|
539
541
|
options: Pick<PluginOptions, 'onlyIncludeVersions'>,
|
|
@@ -547,8 +549,7 @@ function filterVersions(
|
|
|
547
549
|
}
|
|
548
550
|
}
|
|
549
551
|
|
|
550
|
-
|
|
551
|
-
export function readVersionsMetadata({
|
|
552
|
+
export async function readVersionsMetadata({
|
|
552
553
|
context,
|
|
553
554
|
options,
|
|
554
555
|
}: {
|
|
@@ -568,8 +569,11 @@ export function readVersionsMetadata({
|
|
|
568
569
|
| 'editUrl'
|
|
569
570
|
| 'editCurrentVersion'
|
|
570
571
|
>;
|
|
571
|
-
}): VersionMetadata[] {
|
|
572
|
-
const versionNamesUnfiltered = readVersionNames(
|
|
572
|
+
}): Promise<VersionMetadata[]> {
|
|
573
|
+
const versionNamesUnfiltered = await readVersionNames(
|
|
574
|
+
context.siteDir,
|
|
575
|
+
options,
|
|
576
|
+
);
|
|
573
577
|
|
|
574
578
|
checkVersionsOptions(versionNamesUnfiltered, options);
|
|
575
579
|
|