@docusaurus/plugin-content-docs 0.0.0-5961 → 0.0.0-5963
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/docs.d.ts +2 -0
- package/lib/docs.js +9 -2
- package/lib/index.js +34 -10
- package/lib/options.js +9 -0
- package/lib/props.js +2 -0
- package/lib/routes.js +21 -4
- package/lib/types.d.ts +2 -5
- package/package.json +10 -10
- package/src/docs.ts +14 -2
- package/src/index.ts +47 -12
- package/src/options.ts +9 -0
- package/src/plugin-content-docs.d.ts +4 -3
- package/src/props.ts +2 -0
- package/src/routes.ts +23 -4
- package/src/types.ts +2 -6
- package/lib/tags.d.ts +0 -10
- package/lib/tags.js +0 -28
- package/src/tags.ts +0 -27
package/lib/docs.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
/// <reference path="../src/plugin-content-docs.d.ts" />
|
|
8
|
+
import type { TagsFile } from '@docusaurus/utils';
|
|
8
9
|
import type { MetadataOptions, PluginOptions, CategoryIndexMatcher, DocMetadataBase, VersionMetadata, LoadedVersion } from '@docusaurus/plugin-content-docs';
|
|
9
10
|
import type { LoadContext } from '@docusaurus/types';
|
|
10
11
|
import type { SidebarsUtils } from './sidebars/utils';
|
|
@@ -18,6 +19,7 @@ export declare function processDocMetadata(args: {
|
|
|
18
19
|
context: LoadContext;
|
|
19
20
|
options: MetadataOptions;
|
|
20
21
|
env: DocEnv;
|
|
22
|
+
tagsFile: TagsFile | null;
|
|
21
23
|
}): Promise<DocMetadataBase>;
|
|
22
24
|
export declare function addDocNavigation({ docs, sidebarsUtils, }: {
|
|
23
25
|
docs: DocMetadataBase[];
|
package/lib/docs.js
CHANGED
|
@@ -31,7 +31,7 @@ async function readVersionDocs(versionMetadata, options) {
|
|
|
31
31
|
return Promise.all(sources.map((source) => readDocFile(versionMetadata, source)));
|
|
32
32
|
}
|
|
33
33
|
exports.readVersionDocs = readVersionDocs;
|
|
34
|
-
async function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, }) {
|
|
34
|
+
async function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, tagsFile, }) {
|
|
35
35
|
const { source, content, contentPath, filePath } = docFile;
|
|
36
36
|
const { siteDir, siteConfig: { markdown: { parseFrontMatter }, }, } = context;
|
|
37
37
|
const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = await (0, utils_1.parseMarkdownFile)({
|
|
@@ -108,6 +108,13 @@ async function doProcessDocMetadata({ docFile, versionMetadata, context, options
|
|
|
108
108
|
}
|
|
109
109
|
const draft = (0, utils_1.isDraft)({ env, frontMatter });
|
|
110
110
|
const unlisted = (0, utils_1.isUnlisted)({ env, frontMatter });
|
|
111
|
+
const tags = (0, utils_1.normalizeTags)({
|
|
112
|
+
options,
|
|
113
|
+
source,
|
|
114
|
+
frontMatterTags: frontMatter.tags,
|
|
115
|
+
tagsBaseRoutePath: versionMetadata.tagsPath,
|
|
116
|
+
tagsFile,
|
|
117
|
+
});
|
|
111
118
|
// Assign all of object properties during instantiation (if possible) for
|
|
112
119
|
// NodeJS optimization.
|
|
113
120
|
// Adding properties to object after instantiation will cause hidden
|
|
@@ -123,7 +130,7 @@ async function doProcessDocMetadata({ docFile, versionMetadata, context, options
|
|
|
123
130
|
draft,
|
|
124
131
|
unlisted,
|
|
125
132
|
editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
|
|
126
|
-
tags
|
|
133
|
+
tags,
|
|
127
134
|
version: versionMetadata.versionName,
|
|
128
135
|
lastUpdatedBy: lastUpdate.lastUpdatedBy,
|
|
129
136
|
lastUpdatedAt: lastUpdate.lastUpdatedAt,
|
package/lib/index.js
CHANGED
|
@@ -12,6 +12,7 @@ const path_1 = tslib_1.__importDefault(require("path"));
|
|
|
12
12
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
13
13
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
14
14
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
+
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
15
16
|
const sidebars_1 = require("./sidebars");
|
|
16
17
|
const generator_1 = require("./sidebars/generator");
|
|
17
18
|
const docs_1 = require("./docs");
|
|
@@ -22,6 +23,25 @@ const globalData_1 = require("./globalData");
|
|
|
22
23
|
const translations_1 = require("./translations");
|
|
23
24
|
const routes_1 = require("./routes");
|
|
24
25
|
const utils_2 = require("./sidebars/utils");
|
|
26
|
+
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
27
|
+
// The source to permalink is currently a mutable map passed to the mdx loader
|
|
28
|
+
// for link resolution
|
|
29
|
+
// see https://github.com/facebook/docusaurus/pull/10185
|
|
30
|
+
function createSourceToPermalinkHelper() {
|
|
31
|
+
const sourceToPermalink = new Map();
|
|
32
|
+
function computeSourceToPermalink(content) {
|
|
33
|
+
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
|
34
|
+
return new Map(allDocs.map(({ source, permalink }) => [source, permalink]));
|
|
35
|
+
}
|
|
36
|
+
// Mutable map update :/
|
|
37
|
+
function update(content) {
|
|
38
|
+
sourceToPermalink.clear();
|
|
39
|
+
computeSourceToPermalink(content).forEach((value, key) => {
|
|
40
|
+
sourceToPermalink.set(key, value);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return { get: () => sourceToPermalink, update };
|
|
44
|
+
}
|
|
25
45
|
async function pluginContentDocs(context, options) {
|
|
26
46
|
const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
|
|
27
47
|
// Mutate options to resolve sidebar path according to siteDir
|
|
@@ -36,6 +56,7 @@ async function pluginContentDocs(context, options) {
|
|
|
36
56
|
const aliasedSource = (source) => `~docs/${(0, utils_1.posixPath)(path_1.default.relative(pluginDataDirRoot, source))}`;
|
|
37
57
|
// TODO env should be injected into all plugins
|
|
38
58
|
const env = process.env.NODE_ENV;
|
|
59
|
+
const sourceToPermalinkHelper = createSourceToPermalinkHelper();
|
|
39
60
|
return {
|
|
40
61
|
name: 'docusaurus-plugin-content-docs',
|
|
41
62
|
extendCli(cli) {
|
|
@@ -61,6 +82,10 @@ async function pluginContentDocs(context, options) {
|
|
|
61
82
|
function getVersionPathsToWatch(version) {
|
|
62
83
|
const result = [
|
|
63
84
|
...options.include.flatMap((pattern) => (0, utils_1.getContentPathList)(version).map((docsDirPath) => `${docsDirPath}/${pattern}`)),
|
|
85
|
+
...(0, utils_validation_1.getTagsFilePathsToWatch)({
|
|
86
|
+
contentPaths: version,
|
|
87
|
+
tags: options.tags,
|
|
88
|
+
}),
|
|
64
89
|
`${version.contentPath}/**/${generator_1.CategoryMetadataFilenamePattern}`,
|
|
65
90
|
];
|
|
66
91
|
if (typeof version.sidebarFilePath === 'string') {
|
|
@@ -71,7 +96,7 @@ async function pluginContentDocs(context, options) {
|
|
|
71
96
|
return versionsMetadata.flatMap(getVersionPathsToWatch);
|
|
72
97
|
},
|
|
73
98
|
async loadContent() {
|
|
74
|
-
async function loadVersionDocsBase(versionMetadata) {
|
|
99
|
+
async function loadVersionDocsBase(versionMetadata, tagsFile) {
|
|
75
100
|
const docFiles = await (0, docs_1.readVersionDocs)(versionMetadata, options);
|
|
76
101
|
if (docFiles.length === 0) {
|
|
77
102
|
throw new Error(`Docs version "${versionMetadata.versionName}" has no docs! At least one doc should exist at "${path_1.default.relative(siteDir, versionMetadata.contentPath)}".`);
|
|
@@ -83,12 +108,17 @@ async function pluginContentDocs(context, options) {
|
|
|
83
108
|
context,
|
|
84
109
|
options,
|
|
85
110
|
env,
|
|
111
|
+
tagsFile,
|
|
86
112
|
});
|
|
87
113
|
}
|
|
88
114
|
return Promise.all(docFiles.map(processVersionDoc));
|
|
89
115
|
}
|
|
90
116
|
async function doLoadVersion(versionMetadata) {
|
|
91
|
-
const
|
|
117
|
+
const tagsFile = await (0, utils_validation_1.getTagsFile)({
|
|
118
|
+
contentPaths: versionMetadata,
|
|
119
|
+
tags: options.tags,
|
|
120
|
+
});
|
|
121
|
+
const docsBase = await loadVersionDocsBase(versionMetadata, tagsFile);
|
|
92
122
|
// TODO we only ever need draftIds in further code, not full draft items
|
|
93
123
|
// To simplify and prevent mistakes, avoid exposing draft
|
|
94
124
|
// replace draft=>draftIds in content loaded
|
|
@@ -144,6 +174,7 @@ async function pluginContentDocs(context, options) {
|
|
|
144
174
|
return (0, translations_1.translateLoadedContent)(content, translationFiles);
|
|
145
175
|
},
|
|
146
176
|
async contentLoaded({ content, actions }) {
|
|
177
|
+
sourceToPermalinkHelper.update(content);
|
|
147
178
|
const versions = content.loadedVersions.map(versions_1.toFullVersion);
|
|
148
179
|
await (0, routes_1.createAllRoutes)({
|
|
149
180
|
baseUrl,
|
|
@@ -164,13 +195,6 @@ async function pluginContentDocs(context, options) {
|
|
|
164
195
|
.flatMap(utils_1.getContentPathList)
|
|
165
196
|
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
166
197
|
.map(utils_1.addTrailingPathSeparator);
|
|
167
|
-
// TODO this does not re-run when content gets updated in dev!
|
|
168
|
-
// it's probably better to restore a mutable cache in the plugin
|
|
169
|
-
function getSourceToPermalink() {
|
|
170
|
-
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
|
171
|
-
return Object.fromEntries(allDocs.map(({ source, permalink }) => [source, permalink]));
|
|
172
|
-
}
|
|
173
|
-
const sourceToPermalink = getSourceToPermalink();
|
|
174
198
|
function createMDXLoader() {
|
|
175
199
|
const loaderOptions = {
|
|
176
200
|
admonitions: options.admonitions,
|
|
@@ -197,7 +221,7 @@ async function pluginContentDocs(context, options) {
|
|
|
197
221
|
const version = (0, versions_1.getVersionFromSourceFilePath)(sourceFilePath, content.loadedVersions);
|
|
198
222
|
const permalink = (0, utils_1.resolveMarkdownLinkPathname)(linkPathname, {
|
|
199
223
|
sourceFilePath,
|
|
200
|
-
sourceToPermalink,
|
|
224
|
+
sourceToPermalink: sourceToPermalinkHelper.get(),
|
|
201
225
|
siteDir,
|
|
202
226
|
contentPaths: version,
|
|
203
227
|
});
|
package/lib/options.js
CHANGED
|
@@ -44,6 +44,8 @@ exports.DEFAULT_OPTIONS = {
|
|
|
44
44
|
sidebarCollapsible: true,
|
|
45
45
|
sidebarCollapsed: true,
|
|
46
46
|
breadcrumbs: true,
|
|
47
|
+
onInlineTags: 'warn',
|
|
48
|
+
tags: undefined,
|
|
47
49
|
};
|
|
48
50
|
const VersionOptionsSchema = utils_validation_1.Joi.object({
|
|
49
51
|
path: utils_validation_1.Joi.string().allow('').optional(),
|
|
@@ -100,6 +102,13 @@ const OptionsSchema = utils_validation_1.Joi.object({
|
|
|
100
102
|
lastVersion: utils_validation_1.Joi.string().optional(),
|
|
101
103
|
versions: VersionsOptionsSchema,
|
|
102
104
|
breadcrumbs: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.breadcrumbs),
|
|
105
|
+
onInlineTags: utils_validation_1.Joi.string()
|
|
106
|
+
.equal('ignore', 'log', 'warn', 'throw')
|
|
107
|
+
.default(exports.DEFAULT_OPTIONS.onInlineTags),
|
|
108
|
+
tags: utils_validation_1.Joi.string()
|
|
109
|
+
.disallow('')
|
|
110
|
+
.allow(null, false)
|
|
111
|
+
.default(() => exports.DEFAULT_OPTIONS.tags),
|
|
103
112
|
});
|
|
104
113
|
function validateOptions({ validate, options: userOptions, }) {
|
|
105
114
|
let options = userOptions;
|
package/lib/props.js
CHANGED
|
@@ -134,6 +134,7 @@ function toTagDocListProp({ allTagsPath, tag, docs, }) {
|
|
|
134
134
|
return {
|
|
135
135
|
label: tag.label,
|
|
136
136
|
permalink: tag.permalink,
|
|
137
|
+
description: tag.description,
|
|
137
138
|
allTagsPath,
|
|
138
139
|
count: tag.docIds.length,
|
|
139
140
|
items: toDocListProp(),
|
|
@@ -147,6 +148,7 @@ function toTagsListTagsProp(versionTags) {
|
|
|
147
148
|
.map((tagValue) => ({
|
|
148
149
|
label: tagValue.label,
|
|
149
150
|
permalink: tagValue.permalink,
|
|
151
|
+
description: tagValue.description,
|
|
150
152
|
count: tagValue.docIds.length,
|
|
151
153
|
}));
|
|
152
154
|
}
|
package/lib/routes.js
CHANGED
|
@@ -12,7 +12,6 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
|
12
12
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
13
13
|
const utils_1 = require("@docusaurus/utils");
|
|
14
14
|
const props_1 = require("./props");
|
|
15
|
-
const tags_1 = require("./tags");
|
|
16
15
|
function createDocRouteMetadata(docMeta) {
|
|
17
16
|
return {
|
|
18
17
|
sourceFilePath: (0, utils_1.aliasedSitePathToRelativePath)(docMeta.source),
|
|
@@ -74,12 +73,30 @@ async function buildVersionSidebarRoute(param) {
|
|
|
74
73
|
routes: subRoutes,
|
|
75
74
|
};
|
|
76
75
|
}
|
|
76
|
+
function getVersionTags(docs) {
|
|
77
|
+
const groups = (0, utils_1.groupTaggedItems)(docs, (doc) => doc.tags);
|
|
78
|
+
return lodash_1.default.mapValues(groups, ({ tag, items: tagDocs }) => {
|
|
79
|
+
const tagVisibility = (0, utils_1.getTagVisibility)({
|
|
80
|
+
items: tagDocs,
|
|
81
|
+
isUnlisted: (item) => item.unlisted,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
inline: tag.inline,
|
|
85
|
+
label: tag.label,
|
|
86
|
+
permalink: tag.permalink,
|
|
87
|
+
description: tag.description,
|
|
88
|
+
docIds: tagVisibility.listedItems.map((item) => item.id),
|
|
89
|
+
unlisted: tagVisibility.unlisted,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
77
93
|
async function buildVersionTagsRoutes(param) {
|
|
78
94
|
const { version, options } = param;
|
|
79
|
-
const versionTags =
|
|
95
|
+
const versionTags = getVersionTags(version.docs);
|
|
80
96
|
async function buildTagsListRoute() {
|
|
97
|
+
const tags = (0, props_1.toTagsListTagsProp)(versionTags);
|
|
81
98
|
// Don't create a tags list page if there's no tag
|
|
82
|
-
if (
|
|
99
|
+
if (tags.length === 0) {
|
|
83
100
|
return null;
|
|
84
101
|
}
|
|
85
102
|
return {
|
|
@@ -87,7 +104,7 @@ async function buildVersionTagsRoutes(param) {
|
|
|
87
104
|
exact: true,
|
|
88
105
|
component: options.docTagsListComponent,
|
|
89
106
|
props: {
|
|
90
|
-
tags
|
|
107
|
+
tags,
|
|
91
108
|
},
|
|
92
109
|
};
|
|
93
110
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
/// <reference path="../src/plugin-content-docs.d.ts" />
|
|
8
|
-
import type {
|
|
8
|
+
import type { TagMetadata } from '@docusaurus/utils';
|
|
9
9
|
import type { LoadedVersion, CategoryGeneratedIndexMetadata } from '@docusaurus/plugin-content-docs';
|
|
10
10
|
import type { SidebarsUtils } from './sidebars/utils';
|
|
11
11
|
export type DocFile = {
|
|
@@ -14,10 +14,7 @@ export type DocFile = {
|
|
|
14
14
|
source: string;
|
|
15
15
|
content: string;
|
|
16
16
|
};
|
|
17
|
-
export type
|
|
18
|
-
[source: string]: string;
|
|
19
|
-
};
|
|
20
|
-
export type VersionTag = Tag & {
|
|
17
|
+
export type VersionTag = TagMetadata & {
|
|
21
18
|
/** All doc ids having this tag. */
|
|
22
19
|
docIds: string[];
|
|
23
20
|
unlisted: boolean;
|
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-5963",
|
|
4
4
|
"description": "Docs plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
},
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@docusaurus/core": "0.0.0-
|
|
39
|
-
"@docusaurus/logger": "0.0.0-
|
|
40
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
41
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
42
|
-
"@docusaurus/types": "0.0.0-
|
|
43
|
-
"@docusaurus/utils": "0.0.0-
|
|
44
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
45
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
38
|
+
"@docusaurus/core": "0.0.0-5963",
|
|
39
|
+
"@docusaurus/logger": "0.0.0-5963",
|
|
40
|
+
"@docusaurus/mdx-loader": "0.0.0-5963",
|
|
41
|
+
"@docusaurus/module-type-aliases": "0.0.0-5963",
|
|
42
|
+
"@docusaurus/types": "0.0.0-5963",
|
|
43
|
+
"@docusaurus/utils": "0.0.0-5963",
|
|
44
|
+
"@docusaurus/utils-common": "0.0.0-5963",
|
|
45
|
+
"@docusaurus/utils-validation": "0.0.0-5963",
|
|
46
46
|
"@types/react-router-config": "^5.0.7",
|
|
47
47
|
"combine-promises": "^1.1.0",
|
|
48
48
|
"fs-extra": "^11.1.1",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=18.0"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "e9090dc8a38a21043b0849887aa7d54d04c4af9f"
|
|
70
70
|
}
|
package/src/docs.ts
CHANGED
|
@@ -17,15 +17,16 @@ import {
|
|
|
17
17
|
parseMarkdownFile,
|
|
18
18
|
posixPath,
|
|
19
19
|
Globby,
|
|
20
|
-
normalizeFrontMatterTags,
|
|
21
20
|
isUnlisted,
|
|
22
21
|
isDraft,
|
|
23
22
|
readLastUpdateData,
|
|
23
|
+
normalizeTags,
|
|
24
24
|
} from '@docusaurus/utils';
|
|
25
25
|
import {validateDocFrontMatter} from './frontMatter';
|
|
26
26
|
import getSlug from './slug';
|
|
27
27
|
import {stripPathNumberPrefixes} from './numberPrefix';
|
|
28
28
|
import {toDocNavigationLink, toNavigationLink} from './sidebars/utils';
|
|
29
|
+
import type {TagsFile} from '@docusaurus/utils';
|
|
29
30
|
import type {
|
|
30
31
|
MetadataOptions,
|
|
31
32
|
PluginOptions,
|
|
@@ -82,12 +83,14 @@ async function doProcessDocMetadata({
|
|
|
82
83
|
context,
|
|
83
84
|
options,
|
|
84
85
|
env,
|
|
86
|
+
tagsFile,
|
|
85
87
|
}: {
|
|
86
88
|
docFile: DocFile;
|
|
87
89
|
versionMetadata: VersionMetadata;
|
|
88
90
|
context: LoadContext;
|
|
89
91
|
options: MetadataOptions;
|
|
90
92
|
env: DocEnv;
|
|
93
|
+
tagsFile: TagsFile | null;
|
|
91
94
|
}): Promise<DocMetadataBase> {
|
|
92
95
|
const {source, content, contentPath, filePath} = docFile;
|
|
93
96
|
const {
|
|
@@ -206,6 +209,14 @@ async function doProcessDocMetadata({
|
|
|
206
209
|
const draft = isDraft({env, frontMatter});
|
|
207
210
|
const unlisted = isUnlisted({env, frontMatter});
|
|
208
211
|
|
|
212
|
+
const tags = normalizeTags({
|
|
213
|
+
options,
|
|
214
|
+
source,
|
|
215
|
+
frontMatterTags: frontMatter.tags,
|
|
216
|
+
tagsBaseRoutePath: versionMetadata.tagsPath,
|
|
217
|
+
tagsFile,
|
|
218
|
+
});
|
|
219
|
+
|
|
209
220
|
// Assign all of object properties during instantiation (if possible) for
|
|
210
221
|
// NodeJS optimization.
|
|
211
222
|
// Adding properties to object after instantiation will cause hidden
|
|
@@ -221,7 +232,7 @@ async function doProcessDocMetadata({
|
|
|
221
232
|
draft,
|
|
222
233
|
unlisted,
|
|
223
234
|
editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
|
|
224
|
-
tags
|
|
235
|
+
tags,
|
|
225
236
|
version: versionMetadata.versionName,
|
|
226
237
|
lastUpdatedBy: lastUpdate.lastUpdatedBy,
|
|
227
238
|
lastUpdatedAt: lastUpdate.lastUpdatedAt,
|
|
@@ -236,6 +247,7 @@ export async function processDocMetadata(args: {
|
|
|
236
247
|
context: LoadContext;
|
|
237
248
|
options: MetadataOptions;
|
|
238
249
|
env: DocEnv;
|
|
250
|
+
tagsFile: TagsFile | null;
|
|
239
251
|
}): Promise<DocMetadataBase> {
|
|
240
252
|
try {
|
|
241
253
|
return await doProcessDocMetadata(args);
|
package/src/index.ts
CHANGED
|
@@ -19,7 +19,13 @@ import {
|
|
|
19
19
|
createSlugger,
|
|
20
20
|
resolveMarkdownLinkPathname,
|
|
21
21
|
DEFAULT_PLUGIN_ID,
|
|
22
|
+
type SourceToPermalink,
|
|
23
|
+
type TagsFile,
|
|
22
24
|
} from '@docusaurus/utils';
|
|
25
|
+
import {
|
|
26
|
+
getTagsFile,
|
|
27
|
+
getTagsFilePathsToWatch,
|
|
28
|
+
} from '@docusaurus/utils-validation';
|
|
23
29
|
import {loadSidebars, resolveSidebarPathOption} from './sidebars';
|
|
24
30
|
import {CategoryMetadataFilenamePattern} from './sidebars/generator';
|
|
25
31
|
import {
|
|
@@ -54,9 +60,32 @@ import type {
|
|
|
54
60
|
LoadedVersion,
|
|
55
61
|
} from '@docusaurus/plugin-content-docs';
|
|
56
62
|
import type {LoadContext, Plugin} from '@docusaurus/types';
|
|
57
|
-
import type {
|
|
63
|
+
import type {DocFile, FullVersion} from './types';
|
|
58
64
|
import type {RuleSetUseItem} from 'webpack';
|
|
59
65
|
|
|
66
|
+
// TODO this is bad, we should have a better way to do this (new lifecycle?)
|
|
67
|
+
// The source to permalink is currently a mutable map passed to the mdx loader
|
|
68
|
+
// for link resolution
|
|
69
|
+
// see https://github.com/facebook/docusaurus/pull/10185
|
|
70
|
+
function createSourceToPermalinkHelper() {
|
|
71
|
+
const sourceToPermalink: SourceToPermalink = new Map();
|
|
72
|
+
|
|
73
|
+
function computeSourceToPermalink(content: LoadedContent): SourceToPermalink {
|
|
74
|
+
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
|
75
|
+
return new Map(allDocs.map(({source, permalink}) => [source, permalink]));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Mutable map update :/
|
|
79
|
+
function update(content: LoadedContent): void {
|
|
80
|
+
sourceToPermalink.clear();
|
|
81
|
+
computeSourceToPermalink(content).forEach((value, key) => {
|
|
82
|
+
sourceToPermalink.set(key, value);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {get: () => sourceToPermalink, update};
|
|
87
|
+
}
|
|
88
|
+
|
|
60
89
|
export default async function pluginContentDocs(
|
|
61
90
|
context: LoadContext,
|
|
62
91
|
options: PluginOptions,
|
|
@@ -83,6 +112,8 @@ export default async function pluginContentDocs(
|
|
|
83
112
|
// TODO env should be injected into all plugins
|
|
84
113
|
const env = process.env.NODE_ENV as DocEnv;
|
|
85
114
|
|
|
115
|
+
const sourceToPermalinkHelper = createSourceToPermalinkHelper();
|
|
116
|
+
|
|
86
117
|
return {
|
|
87
118
|
name: 'docusaurus-plugin-content-docs',
|
|
88
119
|
|
|
@@ -119,6 +150,10 @@ export default async function pluginContentDocs(
|
|
|
119
150
|
(docsDirPath) => `${docsDirPath}/${pattern}`,
|
|
120
151
|
),
|
|
121
152
|
),
|
|
153
|
+
...getTagsFilePathsToWatch({
|
|
154
|
+
contentPaths: version,
|
|
155
|
+
tags: options.tags,
|
|
156
|
+
}),
|
|
122
157
|
`${version.contentPath}/**/${CategoryMetadataFilenamePattern}`,
|
|
123
158
|
];
|
|
124
159
|
if (typeof version.sidebarFilePath === 'string') {
|
|
@@ -133,6 +168,7 @@ export default async function pluginContentDocs(
|
|
|
133
168
|
async loadContent() {
|
|
134
169
|
async function loadVersionDocsBase(
|
|
135
170
|
versionMetadata: VersionMetadata,
|
|
171
|
+
tagsFile: TagsFile | null,
|
|
136
172
|
): Promise<DocMetadataBase[]> {
|
|
137
173
|
const docFiles = await readVersionDocs(versionMetadata, options);
|
|
138
174
|
if (docFiles.length === 0) {
|
|
@@ -152,6 +188,7 @@ export default async function pluginContentDocs(
|
|
|
152
188
|
context,
|
|
153
189
|
options,
|
|
154
190
|
env,
|
|
191
|
+
tagsFile,
|
|
155
192
|
});
|
|
156
193
|
}
|
|
157
194
|
return Promise.all(docFiles.map(processVersionDoc));
|
|
@@ -160,8 +197,14 @@ export default async function pluginContentDocs(
|
|
|
160
197
|
async function doLoadVersion(
|
|
161
198
|
versionMetadata: VersionMetadata,
|
|
162
199
|
): Promise<LoadedVersion> {
|
|
200
|
+
const tagsFile = await getTagsFile({
|
|
201
|
+
contentPaths: versionMetadata,
|
|
202
|
+
tags: options.tags,
|
|
203
|
+
});
|
|
204
|
+
|
|
163
205
|
const docsBase: DocMetadataBase[] = await loadVersionDocsBase(
|
|
164
206
|
versionMetadata,
|
|
207
|
+
tagsFile,
|
|
165
208
|
);
|
|
166
209
|
|
|
167
210
|
// TODO we only ever need draftIds in further code, not full draft items
|
|
@@ -227,6 +270,8 @@ export default async function pluginContentDocs(
|
|
|
227
270
|
},
|
|
228
271
|
|
|
229
272
|
async contentLoaded({content, actions}) {
|
|
273
|
+
sourceToPermalinkHelper.update(content);
|
|
274
|
+
|
|
230
275
|
const versions: FullVersion[] = content.loadedVersions.map(toFullVersion);
|
|
231
276
|
|
|
232
277
|
await createAllRoutes({
|
|
@@ -257,16 +302,6 @@ export default async function pluginContentDocs(
|
|
|
257
302
|
// Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
|
|
258
303
|
.map(addTrailingPathSeparator);
|
|
259
304
|
|
|
260
|
-
// TODO this does not re-run when content gets updated in dev!
|
|
261
|
-
// it's probably better to restore a mutable cache in the plugin
|
|
262
|
-
function getSourceToPermalink(): SourceToPermalink {
|
|
263
|
-
const allDocs = content.loadedVersions.flatMap((v) => v.docs);
|
|
264
|
-
return Object.fromEntries(
|
|
265
|
-
allDocs.map(({source, permalink}) => [source, permalink]),
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
const sourceToPermalink = getSourceToPermalink();
|
|
269
|
-
|
|
270
305
|
function createMDXLoader(): RuleSetUseItem {
|
|
271
306
|
const loaderOptions: MDXLoaderOptions = {
|
|
272
307
|
admonitions: options.admonitions,
|
|
@@ -301,7 +336,7 @@ export default async function pluginContentDocs(
|
|
|
301
336
|
);
|
|
302
337
|
const permalink = resolveMarkdownLinkPathname(linkPathname, {
|
|
303
338
|
sourceFilePath,
|
|
304
|
-
sourceToPermalink,
|
|
339
|
+
sourceToPermalink: sourceToPermalinkHelper.get(),
|
|
305
340
|
siteDir,
|
|
306
341
|
contentPaths: version,
|
|
307
342
|
});
|
package/src/options.ts
CHANGED
|
@@ -54,6 +54,8 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
|
|
|
54
54
|
sidebarCollapsible: true,
|
|
55
55
|
sidebarCollapsed: true,
|
|
56
56
|
breadcrumbs: true,
|
|
57
|
+
onInlineTags: 'warn',
|
|
58
|
+
tags: undefined,
|
|
57
59
|
};
|
|
58
60
|
|
|
59
61
|
const VersionOptionsSchema = Joi.object({
|
|
@@ -140,6 +142,13 @@ const OptionsSchema = Joi.object<PluginOptions>({
|
|
|
140
142
|
lastVersion: Joi.string().optional(),
|
|
141
143
|
versions: VersionsOptionsSchema,
|
|
142
144
|
breadcrumbs: Joi.bool().default(DEFAULT_OPTIONS.breadcrumbs),
|
|
145
|
+
onInlineTags: Joi.string()
|
|
146
|
+
.equal('ignore', 'log', 'warn', 'throw')
|
|
147
|
+
.default(DEFAULT_OPTIONS.onInlineTags),
|
|
148
|
+
tags: Joi.string()
|
|
149
|
+
.disallow('')
|
|
150
|
+
.allow(null, false)
|
|
151
|
+
.default(() => DEFAULT_OPTIONS.tags),
|
|
143
152
|
});
|
|
144
153
|
|
|
145
154
|
export function validateOptions({
|
|
@@ -15,9 +15,10 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
15
15
|
FrontMatterTag,
|
|
16
16
|
TagsListItem,
|
|
17
17
|
TagModule,
|
|
18
|
-
Tag,
|
|
19
18
|
FrontMatterLastUpdate,
|
|
20
19
|
LastUpdateData,
|
|
20
|
+
TagMetadata,
|
|
21
|
+
TagsPluginOptions,
|
|
21
22
|
} from '@docusaurus/utils';
|
|
22
23
|
import type {Plugin, LoadContext} from '@docusaurus/types';
|
|
23
24
|
import type {Overwrite, Required} from 'utility-types';
|
|
@@ -64,7 +65,7 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
64
65
|
locale: string;
|
|
65
66
|
}) => string | undefined;
|
|
66
67
|
|
|
67
|
-
export type MetadataOptions = {
|
|
68
|
+
export type MetadataOptions = TagsPluginOptions & {
|
|
68
69
|
/**
|
|
69
70
|
* URL route for the docs section of your site. **DO NOT** include a
|
|
70
71
|
* trailing slash. Use `/` for shipping docs without base path.
|
|
@@ -446,7 +447,7 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
446
447
|
*/
|
|
447
448
|
editUrl?: string | null;
|
|
448
449
|
/** Tags, normalized. */
|
|
449
|
-
tags:
|
|
450
|
+
tags: TagMetadata[];
|
|
450
451
|
/** Front matter, as-is. */
|
|
451
452
|
frontMatter: DocFrontMatter & {[key: string]: unknown};
|
|
452
453
|
};
|
package/src/props.ts
CHANGED
|
@@ -206,6 +206,7 @@ export function toTagDocListProp({
|
|
|
206
206
|
return {
|
|
207
207
|
label: tag.label,
|
|
208
208
|
permalink: tag.permalink,
|
|
209
|
+
description: tag.description,
|
|
209
210
|
allTagsPath,
|
|
210
211
|
count: tag.docIds.length,
|
|
211
212
|
items: toDocListProp(),
|
|
@@ -221,6 +222,7 @@ export function toTagsListTagsProp(
|
|
|
221
222
|
.map((tagValue) => ({
|
|
222
223
|
label: tagValue.label,
|
|
223
224
|
permalink: tagValue.permalink,
|
|
225
|
+
description: tagValue.description,
|
|
224
226
|
count: tagValue.docIds.length,
|
|
225
227
|
}));
|
|
226
228
|
}
|
package/src/routes.ts
CHANGED
|
@@ -11,19 +11,20 @@ import {
|
|
|
11
11
|
docuHash,
|
|
12
12
|
normalizeUrl,
|
|
13
13
|
aliasedSitePathToRelativePath,
|
|
14
|
+
groupTaggedItems,
|
|
15
|
+
getTagVisibility,
|
|
14
16
|
} from '@docusaurus/utils';
|
|
15
17
|
import {
|
|
16
18
|
toTagDocListProp,
|
|
17
19
|
toTagsListTagsProp,
|
|
18
20
|
toVersionMetadataProp,
|
|
19
21
|
} from './props';
|
|
20
|
-
import {getVersionTags} from './tags';
|
|
21
22
|
import type {
|
|
22
23
|
PluginContentLoadedActions,
|
|
23
24
|
RouteConfig,
|
|
24
25
|
RouteMetadata,
|
|
25
26
|
} from '@docusaurus/types';
|
|
26
|
-
import type {FullVersion, VersionTag} from './types';
|
|
27
|
+
import type {FullVersion, VersionTag, VersionTags} from './types';
|
|
27
28
|
import type {
|
|
28
29
|
CategoryGeneratedIndexMetadata,
|
|
29
30
|
DocMetadata,
|
|
@@ -112,6 +113,23 @@ async function buildVersionSidebarRoute(param: BuildVersionRoutesParam) {
|
|
|
112
113
|
routes: subRoutes,
|
|
113
114
|
};
|
|
114
115
|
}
|
|
116
|
+
function getVersionTags(docs: DocMetadata[]): VersionTags {
|
|
117
|
+
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
|
118
|
+
return _.mapValues(groups, ({tag, items: tagDocs}) => {
|
|
119
|
+
const tagVisibility = getTagVisibility({
|
|
120
|
+
items: tagDocs,
|
|
121
|
+
isUnlisted: (item) => item.unlisted,
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
inline: tag.inline,
|
|
125
|
+
label: tag.label,
|
|
126
|
+
permalink: tag.permalink,
|
|
127
|
+
description: tag.description,
|
|
128
|
+
docIds: tagVisibility.listedItems.map((item) => item.id),
|
|
129
|
+
unlisted: tagVisibility.unlisted,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
115
133
|
|
|
116
134
|
async function buildVersionTagsRoutes(
|
|
117
135
|
param: BuildVersionRoutesParam,
|
|
@@ -120,8 +138,9 @@ async function buildVersionTagsRoutes(
|
|
|
120
138
|
const versionTags = getVersionTags(version.docs);
|
|
121
139
|
|
|
122
140
|
async function buildTagsListRoute(): Promise<RouteConfig | null> {
|
|
141
|
+
const tags = toTagsListTagsProp(versionTags);
|
|
123
142
|
// Don't create a tags list page if there's no tag
|
|
124
|
-
if (
|
|
143
|
+
if (tags.length === 0) {
|
|
125
144
|
return null;
|
|
126
145
|
}
|
|
127
146
|
return {
|
|
@@ -129,7 +148,7 @@ async function buildVersionTagsRoutes(
|
|
|
129
148
|
exact: true,
|
|
130
149
|
component: options.docTagsListComponent,
|
|
131
150
|
props: {
|
|
132
|
-
tags
|
|
151
|
+
tags,
|
|
133
152
|
},
|
|
134
153
|
};
|
|
135
154
|
}
|
package/src/types.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type {TagMetadata} from '@docusaurus/utils';
|
|
9
9
|
import type {
|
|
10
10
|
LoadedVersion,
|
|
11
11
|
CategoryGeneratedIndexMetadata,
|
|
@@ -19,11 +19,7 @@ export type DocFile = {
|
|
|
19
19
|
content: string;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export type
|
|
23
|
-
[source: string]: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type VersionTag = Tag & {
|
|
22
|
+
export type VersionTag = TagMetadata & {
|
|
27
23
|
/** All doc ids having this tag. */
|
|
28
24
|
docIds: string[];
|
|
29
25
|
unlisted: boolean;
|
package/lib/tags.d.ts
DELETED
|
@@ -1,10 +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
|
-
/// <reference path="../src/plugin-content-docs.d.ts" />
|
|
8
|
-
import type { VersionTags } from './types';
|
|
9
|
-
import type { DocMetadata } from '@docusaurus/plugin-content-docs';
|
|
10
|
-
export declare function getVersionTags(docs: DocMetadata[]): VersionTags;
|
package/lib/tags.js
DELETED
|
@@ -1,28 +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.getVersionTags = void 0;
|
|
10
|
-
const tslib_1 = require("tslib");
|
|
11
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
12
|
-
const utils_1 = require("@docusaurus/utils");
|
|
13
|
-
function getVersionTags(docs) {
|
|
14
|
-
const groups = (0, utils_1.groupTaggedItems)(docs, (doc) => doc.tags);
|
|
15
|
-
return lodash_1.default.mapValues(groups, ({ tag, items: tagDocs }) => {
|
|
16
|
-
const tagVisibility = (0, utils_1.getTagVisibility)({
|
|
17
|
-
items: tagDocs,
|
|
18
|
-
isUnlisted: (item) => item.unlisted,
|
|
19
|
-
});
|
|
20
|
-
return {
|
|
21
|
-
label: tag.label,
|
|
22
|
-
docIds: tagVisibility.listedItems.map((item) => item.id),
|
|
23
|
-
permalink: tag.permalink,
|
|
24
|
-
unlisted: tagVisibility.unlisted,
|
|
25
|
-
};
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
exports.getVersionTags = getVersionTags;
|
package/src/tags.ts
DELETED
|
@@ -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
|
-
import _ from 'lodash';
|
|
9
|
-
import {getTagVisibility, groupTaggedItems} from '@docusaurus/utils';
|
|
10
|
-
import type {VersionTags} from './types';
|
|
11
|
-
import type {DocMetadata} from '@docusaurus/plugin-content-docs';
|
|
12
|
-
|
|
13
|
-
export function getVersionTags(docs: DocMetadata[]): VersionTags {
|
|
14
|
-
const groups = groupTaggedItems(docs, (doc) => doc.tags);
|
|
15
|
-
return _.mapValues(groups, ({tag, items: tagDocs}) => {
|
|
16
|
-
const tagVisibility = getTagVisibility({
|
|
17
|
-
items: tagDocs,
|
|
18
|
-
isUnlisted: (item) => item.unlisted,
|
|
19
|
-
});
|
|
20
|
-
return {
|
|
21
|
-
label: tag.label,
|
|
22
|
-
docIds: tagVisibility.listedItems.map((item) => item.id),
|
|
23
|
-
permalink: tag.permalink,
|
|
24
|
-
unlisted: tagVisibility.unlisted,
|
|
25
|
-
};
|
|
26
|
-
});
|
|
27
|
-
}
|