@docusaurus/plugin-content-docs 2.0.0-beta.1 → 2.0.0-beta.10
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/.tsbuildinfo +1 -1
- package/lib/categoryGeneratedIndex.d.ts +12 -0
- package/lib/categoryGeneratedIndex.js +37 -0
- package/lib/cli.d.ts +2 -2
- package/lib/cli.js +12 -34
- package/lib/client/docsClientUtils.d.ts +1 -4
- package/lib/client/docsClientUtils.js +21 -31
- package/lib/docFrontMatter.d.ts +1 -1
- package/lib/docFrontMatter.js +10 -6
- package/lib/docs.d.ts +25 -3
- package/lib/docs.js +125 -38
- package/lib/globalData.d.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +104 -138
- package/lib/lastUpdate.js +9 -10
- package/lib/markdown/index.d.ts +3 -6
- package/lib/markdown/index.js +3 -3
- package/lib/markdown/linkify.js +2 -2
- package/lib/numberPrefix.d.ts +1 -1
- package/lib/options.d.ts +3 -3
- package/lib/options.js +49 -17
- package/lib/props.d.ts +7 -2
- package/lib/props.js +61 -9
- package/lib/routes.d.ts +27 -0
- package/lib/routes.js +105 -0
- package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +5 -2
- package/lib/sidebars/generator.js +216 -0
- package/lib/sidebars/index.d.ts +15 -0
- package/lib/sidebars/index.js +73 -0
- package/lib/sidebars/normalization.d.ts +14 -0
- package/lib/sidebars/normalization.js +77 -0
- package/lib/sidebars/processor.d.ts +18 -0
- package/lib/sidebars/processor.js +85 -0
- package/lib/sidebars/types.d.ts +127 -0
- package/lib/sidebars/types.js +8 -0
- package/lib/sidebars/utils.d.ts +35 -0
- package/lib/sidebars/utils.js +228 -0
- package/lib/sidebars/validation.d.ts +10 -0
- package/lib/sidebars/validation.js +138 -0
- package/lib/slug.d.ts +4 -3
- package/lib/slug.js +27 -15
- package/lib/tags.d.ts +8 -0
- package/lib/tags.js +20 -0
- package/lib/theme/hooks/useDocs.js +24 -21
- package/lib/translations.d.ts +2 -2
- package/lib/translations.js +71 -29
- package/lib/types.d.ts +52 -62
- package/lib/versions.d.ts +3 -3
- package/lib/versions.js +76 -24
- package/package.json +22 -20
- package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
- package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
- package/src/__tests__/__fixtures__/simple-site/docs/hello.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
- package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
- package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +1 -0
- package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
- package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +3 -0
- package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
- package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -73
- package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
- package/src/__tests__/__snapshots__/index.test.ts.snap +753 -112
- package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -18
- package/src/__tests__/cli.test.ts +15 -11
- package/src/__tests__/docFrontMatter.test.ts +195 -40
- package/src/__tests__/docs.test.ts +311 -150
- package/src/__tests__/index.test.ts +112 -69
- package/src/__tests__/lastUpdate.test.ts +3 -2
- package/src/__tests__/options.test.ts +48 -4
- package/src/__tests__/props.test.ts +62 -0
- package/src/__tests__/slug.test.ts +127 -20
- package/src/__tests__/translations.test.ts +7 -2
- package/src/__tests__/versions.test.ts +93 -67
- package/src/categoryGeneratedIndex.ts +57 -0
- package/src/cli.ts +8 -41
- package/src/client/__tests__/docsClientUtils.test.ts +4 -5
- package/src/client/docsClientUtils.ts +19 -41
- package/{types.d.ts → src/deps.d.ts} +0 -0
- package/src/docFrontMatter.ts +13 -7
- package/src/docs.ts +158 -29
- package/src/globalData.ts +6 -1
- package/src/index.ts +134 -179
- package/src/lastUpdate.ts +10 -9
- package/src/markdown/index.ts +8 -12
- package/src/numberPrefix.ts +5 -3
- package/src/options.ts +59 -28
- package/src/plugin-content-docs.d.ts +179 -35
- package/src/props.ts +91 -16
- package/src/routes.ts +173 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
- package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
- package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +36 -6
- package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +143 -18
- package/src/sidebars/__tests__/index.test.ts +204 -0
- package/src/sidebars/__tests__/processor.test.ts +237 -0
- package/src/sidebars/__tests__/utils.test.ts +695 -0
- package/src/sidebars/__tests__/validation.test.ts +105 -0
- package/src/sidebars/generator.ts +310 -0
- package/src/sidebars/index.ts +94 -0
- package/src/sidebars/normalization.ts +112 -0
- package/src/sidebars/processor.ts +154 -0
- package/src/sidebars/types.ts +211 -0
- package/src/sidebars/utils.ts +329 -0
- package/src/sidebars/validation.ts +168 -0
- package/src/slug.ts +32 -17
- package/src/tags.ts +19 -0
- package/src/theme/hooks/useDocs.ts +5 -1
- package/src/translations.ts +103 -47
- package/src/types.ts +67 -105
- package/src/versions.ts +117 -21
- package/lib/sidebarItemsGenerator.js +0 -211
- package/lib/sidebars.d.ts +0 -43
- package/lib/sidebars.js +0 -319
- package/src/__tests__/sidebars.test.ts +0 -639
- package/src/sidebarItemsGenerator.ts +0 -307
- package/src/sidebars.ts +0 -506
package/src/types.ts
CHANGED
|
@@ -5,14 +5,15 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
// eslint-disable-next-line spaced-comment
|
|
9
8
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
10
9
|
|
|
11
10
|
import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
|
|
12
|
-
import {
|
|
11
|
+
import type {Tag, FrontMatterTag, Slugger} from '@docusaurus/utils';
|
|
12
|
+
import type {
|
|
13
13
|
BrokenMarkdownLink as IBrokenMarkdownLink,
|
|
14
14
|
ContentPaths,
|
|
15
15
|
} from '@docusaurus/utils/lib/markdownLinks';
|
|
16
|
+
import type {SidebarItemsGeneratorOption, Sidebars} from './sidebars/types';
|
|
16
17
|
|
|
17
18
|
export type DocFile = {
|
|
18
19
|
contentPath: string; // /!\ may be localized
|
|
@@ -28,8 +29,12 @@ export type VersionMetadata = ContentPaths & {
|
|
|
28
29
|
versionName: VersionName; // 1.0.0
|
|
29
30
|
versionLabel: string; // Version 1.0.0
|
|
30
31
|
versionPath: string; // /baseUrl/docs/1.0.0
|
|
32
|
+
tagsPath: string;
|
|
31
33
|
versionEditUrl?: string | undefined;
|
|
32
34
|
versionEditUrlLocalized?: string | undefined;
|
|
35
|
+
versionBanner: VersionBanner | null;
|
|
36
|
+
versionBadge: boolean;
|
|
37
|
+
versionClassName: string;
|
|
33
38
|
isLast: boolean;
|
|
34
39
|
sidebarFilePath: string | false | undefined; // versioned_sidebars/1.0.0.json
|
|
35
40
|
routePriority: number | undefined; // -1 for the latest docs
|
|
@@ -45,7 +50,6 @@ export type EditUrlFunction = (editUrlParams: {
|
|
|
45
50
|
|
|
46
51
|
export type MetadataOptions = {
|
|
47
52
|
routeBasePath: string;
|
|
48
|
-
homePageId?: string;
|
|
49
53
|
editUrl?: string | EditUrlFunction;
|
|
50
54
|
editCurrentVersion: boolean;
|
|
51
55
|
editLocalizedFiles: boolean;
|
|
@@ -59,9 +63,15 @@ export type PathOptions = {
|
|
|
59
63
|
sidebarPath?: string | false | undefined;
|
|
60
64
|
};
|
|
61
65
|
|
|
66
|
+
// TODO support custom version banner? {type: "error", content: "html content"}
|
|
67
|
+
export type VersionBanner = 'unreleased' | 'unmaintained';
|
|
68
|
+
|
|
62
69
|
export type VersionOptions = {
|
|
63
70
|
path?: string;
|
|
64
71
|
label?: string;
|
|
72
|
+
banner?: 'none' | VersionBanner;
|
|
73
|
+
badge?: boolean;
|
|
74
|
+
className?: string;
|
|
65
75
|
};
|
|
66
76
|
|
|
67
77
|
export type VersionsOptions = {
|
|
@@ -70,111 +80,36 @@ export type VersionsOptions = {
|
|
|
70
80
|
onlyIncludeVersions?: string[];
|
|
71
81
|
};
|
|
72
82
|
|
|
83
|
+
export type SidebarOptions = {
|
|
84
|
+
sidebarCollapsible: boolean;
|
|
85
|
+
sidebarCollapsed: boolean;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export type NormalizeSidebarsParams = SidebarOptions & {
|
|
89
|
+
version: VersionMetadata;
|
|
90
|
+
categoryLabelSlugger: Slugger;
|
|
91
|
+
};
|
|
92
|
+
|
|
73
93
|
export type PluginOptions = MetadataOptions &
|
|
74
94
|
PathOptions &
|
|
75
95
|
VersionsOptions &
|
|
76
|
-
RemarkAndRehypePluginOptions &
|
|
96
|
+
RemarkAndRehypePluginOptions &
|
|
97
|
+
SidebarOptions & {
|
|
77
98
|
id: string;
|
|
78
99
|
include: string[];
|
|
100
|
+
exclude: string[];
|
|
79
101
|
docLayoutComponent: string;
|
|
80
102
|
docItemComponent: string;
|
|
103
|
+
docTagDocListComponent: string;
|
|
104
|
+
docTagsListComponent: string;
|
|
105
|
+
docCategoryGeneratedIndexComponent: string;
|
|
81
106
|
admonitions: Record<string, unknown>;
|
|
82
107
|
disableVersioning: boolean;
|
|
83
|
-
excludeNextVersionDocs?: boolean;
|
|
84
108
|
includeCurrentVersion: boolean;
|
|
85
109
|
sidebarItemsGenerator: SidebarItemsGeneratorOption;
|
|
110
|
+
tagsBasePath: string;
|
|
86
111
|
};
|
|
87
112
|
|
|
88
|
-
export type SidebarItemBase = {
|
|
89
|
-
customProps?: Record<string, unknown>;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export type SidebarItemDoc = SidebarItemBase & {
|
|
93
|
-
type: 'doc' | 'ref';
|
|
94
|
-
label?: string;
|
|
95
|
-
id: string;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export type SidebarItemLink = SidebarItemBase & {
|
|
99
|
-
type: 'link';
|
|
100
|
-
href: string;
|
|
101
|
-
label: string;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export type SidebarItemCategory = SidebarItemBase & {
|
|
105
|
-
type: 'category';
|
|
106
|
-
label: string;
|
|
107
|
-
items: SidebarItem[];
|
|
108
|
-
collapsed: boolean;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export type UnprocessedSidebarItemAutogenerated = {
|
|
112
|
-
type: 'autogenerated';
|
|
113
|
-
dirName: string;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export type UnprocessedSidebarItemCategory = SidebarItemBase & {
|
|
117
|
-
type: 'category';
|
|
118
|
-
label: string;
|
|
119
|
-
items: UnprocessedSidebarItem[];
|
|
120
|
-
collapsed: boolean;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
export type UnprocessedSidebarItem =
|
|
124
|
-
| SidebarItemDoc
|
|
125
|
-
| SidebarItemLink
|
|
126
|
-
| UnprocessedSidebarItemCategory
|
|
127
|
-
| UnprocessedSidebarItemAutogenerated;
|
|
128
|
-
|
|
129
|
-
export type UnprocessedSidebar = UnprocessedSidebarItem[];
|
|
130
|
-
export type UnprocessedSidebars = Record<string, UnprocessedSidebar>;
|
|
131
|
-
|
|
132
|
-
export type SidebarItem =
|
|
133
|
-
| SidebarItemDoc
|
|
134
|
-
| SidebarItemLink
|
|
135
|
-
| SidebarItemCategory;
|
|
136
|
-
|
|
137
|
-
export type Sidebar = SidebarItem[];
|
|
138
|
-
export type SidebarItemType = SidebarItem['type'];
|
|
139
|
-
export type Sidebars = Record<string, Sidebar>;
|
|
140
|
-
|
|
141
|
-
// Reduce API surface for options.sidebarItemsGenerator
|
|
142
|
-
// The user-provided generator fn should receive only a subset of metadatas
|
|
143
|
-
// A change to any of these metadatas can be considered as a breaking change
|
|
144
|
-
export type SidebarItemsGeneratorDoc = Pick<
|
|
145
|
-
DocMetadataBase,
|
|
146
|
-
'id' | 'frontMatter' | 'source' | 'sourceDirName' | 'sidebarPosition'
|
|
147
|
-
>;
|
|
148
|
-
export type SidebarItemsGeneratorVersion = Pick<
|
|
149
|
-
VersionMetadata,
|
|
150
|
-
'versionName' | 'contentPath'
|
|
151
|
-
>;
|
|
152
|
-
|
|
153
|
-
export type SidebarItemsGeneratorArgs = {
|
|
154
|
-
item: UnprocessedSidebarItemAutogenerated;
|
|
155
|
-
version: SidebarItemsGeneratorVersion;
|
|
156
|
-
docs: SidebarItemsGeneratorDoc[];
|
|
157
|
-
numberPrefixParser: NumberPrefixParser;
|
|
158
|
-
};
|
|
159
|
-
export type SidebarItemsGenerator = (
|
|
160
|
-
generatorArgs: SidebarItemsGeneratorArgs,
|
|
161
|
-
) => Promise<SidebarItem[]>;
|
|
162
|
-
|
|
163
|
-
// Also inject the default generator to conveniently wrap/enhance/sort the default sidebar gen logic
|
|
164
|
-
// see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
|
|
165
|
-
export type SidebarItemsGeneratorOptionArgs = {
|
|
166
|
-
defaultSidebarItemsGenerator: SidebarItemsGenerator;
|
|
167
|
-
} & SidebarItemsGeneratorArgs;
|
|
168
|
-
export type SidebarItemsGeneratorOption = (
|
|
169
|
-
generatorArgs: SidebarItemsGeneratorOptionArgs,
|
|
170
|
-
) => Promise<SidebarItem[]>;
|
|
171
|
-
|
|
172
|
-
export type OrderMetadata = {
|
|
173
|
-
previous?: string;
|
|
174
|
-
next?: string;
|
|
175
|
-
sidebar?: string;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
113
|
export type LastUpdateData = {
|
|
179
114
|
lastUpdatedAt?: number;
|
|
180
115
|
formattedLastUpdatedAt?: string;
|
|
@@ -182,8 +117,10 @@ export type LastUpdateData = {
|
|
|
182
117
|
};
|
|
183
118
|
|
|
184
119
|
export type DocFrontMatter = {
|
|
120
|
+
// Front matter uses snake case
|
|
185
121
|
id?: string;
|
|
186
122
|
title?: string;
|
|
123
|
+
tags?: FrontMatterTag[];
|
|
187
124
|
hide_title?: boolean;
|
|
188
125
|
hide_table_of_contents?: boolean;
|
|
189
126
|
keywords?: string[];
|
|
@@ -192,25 +129,29 @@ export type DocFrontMatter = {
|
|
|
192
129
|
slug?: string;
|
|
193
130
|
sidebar_label?: string;
|
|
194
131
|
sidebar_position?: number;
|
|
132
|
+
sidebar_class_name?: string;
|
|
195
133
|
pagination_label?: string;
|
|
196
134
|
custom_edit_url?: string | null;
|
|
197
135
|
parse_number_prefixes?: boolean;
|
|
136
|
+
toc_min_heading_level?: number;
|
|
137
|
+
toc_max_heading_level?: number;
|
|
138
|
+
pagination_next?: string | null;
|
|
139
|
+
pagination_prev?: string | null;
|
|
198
140
|
};
|
|
199
141
|
|
|
200
142
|
export type DocMetadataBase = LastUpdateData & {
|
|
143
|
+
id: string; // TODO legacy versioned id => try to remove
|
|
144
|
+
unversionedId: string; // TODO new unversioned id => try to rename to "id"
|
|
201
145
|
version: VersionName;
|
|
202
|
-
unversionedId: string;
|
|
203
|
-
id: string;
|
|
204
|
-
isDocsHomePage: boolean;
|
|
205
146
|
title: string;
|
|
206
147
|
description: string;
|
|
207
|
-
source: string;
|
|
208
|
-
sourceDirName: string; // relative to the docs folder (can be ".")
|
|
148
|
+
source: string; // @site aliased source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
|
|
149
|
+
sourceDirName: string; // relative to the versioned docs folder (can be ".") => "folder/subFolder/subSubFolder"
|
|
209
150
|
slug: string;
|
|
210
151
|
permalink: string;
|
|
211
|
-
// eslint-disable-next-line camelcase
|
|
212
152
|
sidebarPosition?: number;
|
|
213
153
|
editUrl?: string | null;
|
|
154
|
+
tags: Tag[];
|
|
214
155
|
frontMatter: DocFrontMatter & Record<string, unknown>;
|
|
215
156
|
};
|
|
216
157
|
|
|
@@ -225,15 +166,35 @@ export type DocMetadata = DocMetadataBase & {
|
|
|
225
166
|
next?: DocNavLink;
|
|
226
167
|
};
|
|
227
168
|
|
|
169
|
+
export type CategoryGeneratedIndexMetadata = {
|
|
170
|
+
title: string;
|
|
171
|
+
description?: string;
|
|
172
|
+
slug: string;
|
|
173
|
+
permalink: string;
|
|
174
|
+
sidebar: string;
|
|
175
|
+
previous?: DocNavLink;
|
|
176
|
+
next?: DocNavLink;
|
|
177
|
+
};
|
|
178
|
+
|
|
228
179
|
export type SourceToPermalink = {
|
|
229
180
|
[source: string]: string;
|
|
230
181
|
};
|
|
182
|
+
|
|
183
|
+
export type VersionTag = {
|
|
184
|
+
name: string; // normalized name/label of the tag
|
|
185
|
+
docIds: string[]; // all doc ids having this tag
|
|
186
|
+
permalink: string; // pathname of the tag
|
|
187
|
+
};
|
|
188
|
+
export type VersionTags = {
|
|
189
|
+
[key: string]: VersionTag;
|
|
190
|
+
};
|
|
191
|
+
|
|
231
192
|
export type LoadedVersion = VersionMetadata & {
|
|
232
193
|
versionPath: string;
|
|
233
194
|
mainDocId: string;
|
|
234
195
|
docs: DocMetadata[];
|
|
235
196
|
sidebars: Sidebars;
|
|
236
|
-
|
|
197
|
+
categoryGeneratedIndices: CategoryGeneratedIndexMetadata[];
|
|
237
198
|
};
|
|
238
199
|
|
|
239
200
|
export type LoadedContent = {
|
|
@@ -269,6 +230,7 @@ export type DocsMarkdownOption = {
|
|
|
269
230
|
onBrokenMarkdownLink: (brokenMarkdownLink: BrokenMarkdownLink) => void;
|
|
270
231
|
};
|
|
271
232
|
|
|
272
|
-
export type NumberPrefixParser = (
|
|
273
|
-
filename: string
|
|
274
|
-
|
|
233
|
+
export type NumberPrefixParser = (filename: string) => {
|
|
234
|
+
filename: string;
|
|
235
|
+
numberPrefix?: number;
|
|
236
|
+
};
|
package/src/versions.ts
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import fs from 'fs-extra';
|
|
10
|
-
import {
|
|
10
|
+
import type {
|
|
11
11
|
PluginOptions,
|
|
12
|
+
VersionBanner,
|
|
12
13
|
VersionMetadata,
|
|
13
14
|
VersionOptions,
|
|
14
15
|
VersionsOptions,
|
|
@@ -20,9 +21,13 @@ import {
|
|
|
20
21
|
CURRENT_VERSION_NAME,
|
|
21
22
|
} from './constants';
|
|
22
23
|
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
|
|
24
|
+
import type {LoadContext} from '@docusaurus/types';
|
|
25
|
+
import {
|
|
26
|
+
getPluginI18nPath,
|
|
27
|
+
normalizeUrl,
|
|
28
|
+
posixPath,
|
|
29
|
+
DEFAULT_PLUGIN_ID,
|
|
30
|
+
} from '@docusaurus/utils';
|
|
26
31
|
import {difference} from 'lodash';
|
|
27
32
|
import {resolveSidebarPathOption} from './sidebars';
|
|
28
33
|
|
|
@@ -255,14 +260,92 @@ function getVersionEditUrls({
|
|
|
255
260
|
};
|
|
256
261
|
}
|
|
257
262
|
|
|
263
|
+
function getDefaultVersionBanner({
|
|
264
|
+
versionName,
|
|
265
|
+
versionNames,
|
|
266
|
+
lastVersionName,
|
|
267
|
+
}: {
|
|
268
|
+
versionName: string;
|
|
269
|
+
versionNames: string[];
|
|
270
|
+
lastVersionName: string;
|
|
271
|
+
}): VersionBanner | null {
|
|
272
|
+
// Current version: good, no banner
|
|
273
|
+
if (versionName === lastVersionName) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
// Upcoming versions: unreleased banner
|
|
277
|
+
else if (
|
|
278
|
+
versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName)
|
|
279
|
+
) {
|
|
280
|
+
return 'unreleased';
|
|
281
|
+
}
|
|
282
|
+
// Older versions: display unmaintained banner
|
|
283
|
+
else {
|
|
284
|
+
return 'unmaintained';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function getVersionBanner({
|
|
289
|
+
versionName,
|
|
290
|
+
versionNames,
|
|
291
|
+
lastVersionName,
|
|
292
|
+
options,
|
|
293
|
+
}: {
|
|
294
|
+
versionName: string;
|
|
295
|
+
versionNames: string[];
|
|
296
|
+
lastVersionName: string;
|
|
297
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
298
|
+
}): VersionBanner | null {
|
|
299
|
+
const versionBannerOption = options.versions[versionName]?.banner;
|
|
300
|
+
if (versionBannerOption) {
|
|
301
|
+
return versionBannerOption === 'none' ? null : versionBannerOption;
|
|
302
|
+
}
|
|
303
|
+
return getDefaultVersionBanner({
|
|
304
|
+
versionName,
|
|
305
|
+
versionNames,
|
|
306
|
+
lastVersionName,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function getVersionBadge({
|
|
311
|
+
versionName,
|
|
312
|
+
versionNames,
|
|
313
|
+
options,
|
|
314
|
+
}: {
|
|
315
|
+
versionName: string;
|
|
316
|
+
versionNames: string[];
|
|
317
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
318
|
+
}): boolean {
|
|
319
|
+
const versionBadgeOption = options.versions[versionName]?.badge;
|
|
320
|
+
// If site is not versioned or only one version is included
|
|
321
|
+
// we don't show the version badge by default
|
|
322
|
+
// See https://github.com/facebook/docusaurus/issues/3362
|
|
323
|
+
const versionBadgeDefault = versionNames.length !== 1;
|
|
324
|
+
return versionBadgeOption ?? versionBadgeDefault;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function getVersionClassName({
|
|
328
|
+
versionName,
|
|
329
|
+
options,
|
|
330
|
+
}: {
|
|
331
|
+
versionName: string;
|
|
332
|
+
options: Pick<PluginOptions, 'versions'>;
|
|
333
|
+
}): string {
|
|
334
|
+
const versionClassNameOption = options.versions[versionName]?.className;
|
|
335
|
+
const versionClassNameDefault = `docs-version-${versionName}`;
|
|
336
|
+
return versionClassNameOption ?? versionClassNameDefault;
|
|
337
|
+
}
|
|
338
|
+
|
|
258
339
|
function createVersionMetadata({
|
|
259
340
|
versionName,
|
|
260
|
-
|
|
341
|
+
versionNames,
|
|
342
|
+
lastVersionName,
|
|
261
343
|
context,
|
|
262
344
|
options,
|
|
263
345
|
}: {
|
|
264
346
|
versionName: string;
|
|
265
|
-
|
|
347
|
+
versionNames: string[];
|
|
348
|
+
lastVersionName: string;
|
|
266
349
|
context: Pick<LoadContext, 'siteDir' | 'baseUrl' | 'i18n'>;
|
|
267
350
|
options: Pick<
|
|
268
351
|
PluginOptions,
|
|
@@ -270,29 +353,27 @@ function createVersionMetadata({
|
|
|
270
353
|
| 'path'
|
|
271
354
|
| 'sidebarPath'
|
|
272
355
|
| 'routeBasePath'
|
|
356
|
+
| 'tagsBasePath'
|
|
273
357
|
| 'versions'
|
|
274
358
|
| 'editUrl'
|
|
275
359
|
| 'editCurrentVersion'
|
|
276
360
|
>;
|
|
277
361
|
}): VersionMetadata {
|
|
278
|
-
const {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
} = getVersionMetadataPaths({
|
|
283
|
-
versionName,
|
|
284
|
-
context,
|
|
285
|
-
options,
|
|
286
|
-
});
|
|
362
|
+
const {sidebarFilePath, contentPath, contentPathLocalized} =
|
|
363
|
+
getVersionMetadataPaths({versionName, context, options});
|
|
364
|
+
|
|
365
|
+
const isLast = versionName === lastVersionName;
|
|
287
366
|
|
|
288
367
|
// retro-compatible values
|
|
289
368
|
const defaultVersionLabel =
|
|
290
369
|
versionName === CURRENT_VERSION_NAME ? 'Next' : versionName;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
: versionName;
|
|
370
|
+
function getDefaultVersionPathPart() {
|
|
371
|
+
if (isLast) {
|
|
372
|
+
return '';
|
|
373
|
+
}
|
|
374
|
+
return versionName === CURRENT_VERSION_NAME ? 'next' : versionName;
|
|
375
|
+
}
|
|
376
|
+
const defaultVersionPathPart = getDefaultVersionPathPart();
|
|
296
377
|
|
|
297
378
|
const versionOptions: VersionOptions = options.versions[versionName] ?? {};
|
|
298
379
|
|
|
@@ -315,12 +396,25 @@ function createVersionMetadata({
|
|
|
315
396
|
// Because /docs/:route` should always be after `/docs/versionName/:route`.
|
|
316
397
|
const routePriority = versionPathPart === '' ? -1 : undefined;
|
|
317
398
|
|
|
399
|
+
// the path that will be used to refer the docs tags
|
|
400
|
+
// example below will be using /docs/tags
|
|
401
|
+
const tagsPath = normalizeUrl([versionPath, options.tagsBasePath]);
|
|
402
|
+
|
|
318
403
|
return {
|
|
319
404
|
versionName,
|
|
320
405
|
versionLabel,
|
|
321
406
|
versionPath,
|
|
407
|
+
tagsPath,
|
|
322
408
|
versionEditUrl: versionEditUrls?.versionEditUrl,
|
|
323
409
|
versionEditUrlLocalized: versionEditUrls?.versionEditUrlLocalized,
|
|
410
|
+
versionBanner: getVersionBanner({
|
|
411
|
+
versionName,
|
|
412
|
+
versionNames,
|
|
413
|
+
lastVersionName,
|
|
414
|
+
options,
|
|
415
|
+
}),
|
|
416
|
+
versionBadge: getVersionBadge({versionName, versionNames, options}),
|
|
417
|
+
versionClassName: getVersionClassName({versionName, options}),
|
|
324
418
|
isLast,
|
|
325
419
|
routePriority,
|
|
326
420
|
sidebarFilePath,
|
|
@@ -465,6 +559,7 @@ export function readVersionsMetadata({
|
|
|
465
559
|
| 'path'
|
|
466
560
|
| 'sidebarPath'
|
|
467
561
|
| 'routeBasePath'
|
|
562
|
+
| 'tagsBasePath'
|
|
468
563
|
| 'includeCurrentVersion'
|
|
469
564
|
| 'disableVersioning'
|
|
470
565
|
| 'lastVersion'
|
|
@@ -486,7 +581,8 @@ export function readVersionsMetadata({
|
|
|
486
581
|
const versionsMetadata = versionNames.map((versionName) =>
|
|
487
582
|
createVersionMetadata({
|
|
488
583
|
versionName,
|
|
489
|
-
|
|
584
|
+
versionNames,
|
|
585
|
+
lastVersionName,
|
|
490
586
|
context,
|
|
491
587
|
options,
|
|
492
588
|
}),
|
|
@@ -1,211 +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.DefaultSidebarItemsGenerator = exports.CategoryMetadataFilenamePattern = exports.CategoryMetadataFilenameBase = void 0;
|
|
10
|
-
const tslib_1 = require("tslib");
|
|
11
|
-
const lodash_1 = require("lodash");
|
|
12
|
-
const utils_1 = require("@docusaurus/utils");
|
|
13
|
-
const utils_validation_1 = require("@docusaurus/utils-validation");
|
|
14
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
15
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
16
|
-
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
|
|
17
|
-
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
18
|
-
const sidebars_1 = require("./sidebars");
|
|
19
|
-
const BreadcrumbSeparator = '/';
|
|
20
|
-
exports.CategoryMetadataFilenameBase = '_category_';
|
|
21
|
-
exports.CategoryMetadataFilenamePattern = '_category_.{json,yml,yaml}';
|
|
22
|
-
const CategoryMetadatasFileSchema = utils_validation_1.Joi.object({
|
|
23
|
-
label: utils_validation_1.Joi.string(),
|
|
24
|
-
position: utils_validation_1.Joi.number(),
|
|
25
|
-
collapsed: utils_validation_1.Joi.boolean(),
|
|
26
|
-
});
|
|
27
|
-
// TODO I now believe we should read all the category metadata files ahead of time: we may need this metadata to customize docs metadata
|
|
28
|
-
// Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
|
|
29
|
-
// TODO later if there is `CategoryFolder/index.md`, we may want to read the metadata as yaml on it
|
|
30
|
-
// see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
|
31
|
-
async function readCategoryMetadatasFile(categoryDirPath) {
|
|
32
|
-
var _a, _b;
|
|
33
|
-
function validateCategoryMetadataFile(content) {
|
|
34
|
-
return utils_validation_1.Joi.attempt(content, CategoryMetadatasFileSchema);
|
|
35
|
-
}
|
|
36
|
-
async function tryReadFile(fileNameWithExtension, parse) {
|
|
37
|
-
// Simpler to use only posix paths for mocking file metadatas in tests
|
|
38
|
-
const filePath = utils_1.posixPath(path_1.default.join(categoryDirPath, fileNameWithExtension));
|
|
39
|
-
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
40
|
-
const contentString = await fs_extra_1.default.readFile(filePath, { encoding: 'utf8' });
|
|
41
|
-
const unsafeContent = parse(contentString);
|
|
42
|
-
try {
|
|
43
|
-
return validateCategoryMetadataFile(unsafeContent);
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
console.error(chalk_1.default.red(`The docs sidebar category metadata file looks invalid!\nPath: ${filePath}`));
|
|
47
|
-
throw e;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return ((_b = (_a = (await tryReadFile(`${exports.CategoryMetadataFilenameBase}.json`, JSON.parse))) !== null && _a !== void 0 ? _a : (await tryReadFile(`${exports.CategoryMetadataFilenameBase}.yml`, js_yaml_1.default.load))) !== null && _b !== void 0 ? _b :
|
|
53
|
-
// eslint-disable-next-line no-return-await
|
|
54
|
-
(await tryReadFile(`${exports.CategoryMetadataFilenameBase}.yaml`, js_yaml_1.default.load)));
|
|
55
|
-
}
|
|
56
|
-
// [...parents, tail]
|
|
57
|
-
function parseBreadcrumb(breadcrumb) {
|
|
58
|
-
return {
|
|
59
|
-
parents: lodash_1.take(breadcrumb, breadcrumb.length - 1),
|
|
60
|
-
tail: lodash_1.last(breadcrumb),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
// Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
|
64
|
-
const DefaultSidebarItemsGenerator = async function defaultSidebarItemsGenerator({ item, docs: allDocs, version, numberPrefixParser, }) {
|
|
65
|
-
// Doc at the root of the autogenerated sidebar dir
|
|
66
|
-
function isRootDoc(doc) {
|
|
67
|
-
return doc.sourceDirName === item.dirName;
|
|
68
|
-
}
|
|
69
|
-
// Doc inside a subfolder of the autogenerated sidebar dir
|
|
70
|
-
function isCategoryDoc(doc) {
|
|
71
|
-
if (isRootDoc(doc)) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
return (
|
|
75
|
-
// autogen dir is . and doc is in subfolder
|
|
76
|
-
item.dirName === '.' ||
|
|
77
|
-
// autogen dir is not . and doc is in subfolder
|
|
78
|
-
// "api/myDoc" startsWith "api/" (note "api2/myDoc" is not included)
|
|
79
|
-
doc.sourceDirName.startsWith(utils_1.addTrailingSlash(item.dirName)));
|
|
80
|
-
}
|
|
81
|
-
function isInAutogeneratedDir(doc) {
|
|
82
|
-
return isRootDoc(doc) || isCategoryDoc(doc);
|
|
83
|
-
}
|
|
84
|
-
// autogenDir=a/b and docDir=a/b/c/d => returns c/d
|
|
85
|
-
// autogenDir=a/b and docDir=a/b => returns .
|
|
86
|
-
function getDocDirRelativeToAutogenDir(doc) {
|
|
87
|
-
if (!isInAutogeneratedDir(doc)) {
|
|
88
|
-
throw new Error('getDocDirRelativeToAutogenDir() can only be called for subdocs of the sidebar autogen dir.');
|
|
89
|
-
}
|
|
90
|
-
// Is there a node API to compare 2 relative paths more easily?
|
|
91
|
-
// path.relative() does not give good results
|
|
92
|
-
if (item.dirName === '.') {
|
|
93
|
-
return doc.sourceDirName;
|
|
94
|
-
}
|
|
95
|
-
else if (item.dirName === doc.sourceDirName) {
|
|
96
|
-
return '.';
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
return doc.sourceDirName.replace(utils_1.addTrailingSlash(item.dirName), '');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// Get only docs in the autogen dir
|
|
103
|
-
// Sort by folder+filename at once
|
|
104
|
-
const docs = lodash_1.sortBy(allDocs.filter(isInAutogeneratedDir), (d) => d.source);
|
|
105
|
-
if (docs.length === 0) {
|
|
106
|
-
console.warn(chalk_1.default.yellow(`No docs found in dir ${item.dirName}: can't auto-generate a sidebar.`));
|
|
107
|
-
}
|
|
108
|
-
function createDocSidebarItem(doc) {
|
|
109
|
-
return {
|
|
110
|
-
type: 'doc',
|
|
111
|
-
id: doc.id,
|
|
112
|
-
...(doc.frontMatter.sidebar_label && {
|
|
113
|
-
label: doc.frontMatter.sidebar_label,
|
|
114
|
-
}),
|
|
115
|
-
...(typeof doc.sidebarPosition !== 'undefined' && {
|
|
116
|
-
position: doc.sidebarPosition,
|
|
117
|
-
}),
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
async function createCategorySidebarItem({ breadcrumb, }) {
|
|
121
|
-
var _a, _b, _c;
|
|
122
|
-
const categoryDirPath = path_1.default.join(version.contentPath, item.dirName, // fix https://github.com/facebook/docusaurus/issues/4638
|
|
123
|
-
breadcrumb.join(BreadcrumbSeparator));
|
|
124
|
-
const categoryMetadatas = await readCategoryMetadatasFile(categoryDirPath);
|
|
125
|
-
const { tail } = parseBreadcrumb(breadcrumb);
|
|
126
|
-
const { filename, numberPrefix } = numberPrefixParser(tail);
|
|
127
|
-
const position = (_a = categoryMetadatas === null || categoryMetadatas === void 0 ? void 0 : categoryMetadatas.position) !== null && _a !== void 0 ? _a : numberPrefix;
|
|
128
|
-
return {
|
|
129
|
-
type: 'category',
|
|
130
|
-
label: (_b = categoryMetadatas === null || categoryMetadatas === void 0 ? void 0 : categoryMetadatas.label) !== null && _b !== void 0 ? _b : filename,
|
|
131
|
-
items: [],
|
|
132
|
-
collapsed: (_c = categoryMetadatas === null || categoryMetadatas === void 0 ? void 0 : categoryMetadatas.collapsed) !== null && _c !== void 0 ? _c : sidebars_1.DefaultCategoryCollapsedValue,
|
|
133
|
-
...(typeof position !== 'undefined' && { position }),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
// Not sure how to simplify this algorithm :/
|
|
137
|
-
async function autogenerateSidebarItems() {
|
|
138
|
-
const sidebarItems = []; // mutable result
|
|
139
|
-
const categoriesByBreadcrumb = {}; // mutable cache of categories already created
|
|
140
|
-
async function getOrCreateCategoriesForBreadcrumb(breadcrumb) {
|
|
141
|
-
if (breadcrumb.length === 0) {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
const { parents } = parseBreadcrumb(breadcrumb);
|
|
145
|
-
const parentCategory = await getOrCreateCategoriesForBreadcrumb(parents);
|
|
146
|
-
const existingCategory = categoriesByBreadcrumb[breadcrumb.join(BreadcrumbSeparator)];
|
|
147
|
-
if (existingCategory) {
|
|
148
|
-
return existingCategory;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
const newCategory = await createCategorySidebarItem({
|
|
152
|
-
breadcrumb,
|
|
153
|
-
});
|
|
154
|
-
if (parentCategory) {
|
|
155
|
-
parentCategory.items.push(newCategory);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
sidebarItems.push(newCategory);
|
|
159
|
-
}
|
|
160
|
-
categoriesByBreadcrumb[breadcrumb.join(BreadcrumbSeparator)] = newCategory;
|
|
161
|
-
return newCategory;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
// Get the category breadcrumb of a doc (relative to the dir of the autogenerated sidebar item)
|
|
165
|
-
function getRelativeBreadcrumb(doc) {
|
|
166
|
-
const relativeDirPath = getDocDirRelativeToAutogenDir(doc);
|
|
167
|
-
if (relativeDirPath === '.') {
|
|
168
|
-
return [];
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
return relativeDirPath.split(BreadcrumbSeparator);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
async function handleDocItem(doc) {
|
|
175
|
-
const breadcrumb = getRelativeBreadcrumb(doc);
|
|
176
|
-
const category = await getOrCreateCategoriesForBreadcrumb(breadcrumb);
|
|
177
|
-
const docSidebarItem = createDocSidebarItem(doc);
|
|
178
|
-
if (category) {
|
|
179
|
-
category.items.push(docSidebarItem);
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
sidebarItems.push(docSidebarItem);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// async process made sequential on purpose! order matters
|
|
186
|
-
for (const doc of docs) {
|
|
187
|
-
// eslint-disable-next-line no-await-in-loop
|
|
188
|
-
await handleDocItem(doc);
|
|
189
|
-
}
|
|
190
|
-
return sidebarItems;
|
|
191
|
-
}
|
|
192
|
-
const sidebarItems = await autogenerateSidebarItems();
|
|
193
|
-
return sortSidebarItems(sidebarItems);
|
|
194
|
-
};
|
|
195
|
-
exports.DefaultSidebarItemsGenerator = DefaultSidebarItemsGenerator;
|
|
196
|
-
// Recursively sort the categories/docs + remove the "position" attribute from final output
|
|
197
|
-
// Note: the "position" is only used to sort "inside" a sidebar slice
|
|
198
|
-
// It is not used to sort across multiple consecutive sidebar slices (ie a whole Category composed of multiple autogenerated items)
|
|
199
|
-
function sortSidebarItems(sidebarItems) {
|
|
200
|
-
const processedSidebarItems = sidebarItems.map((item) => {
|
|
201
|
-
if (item.type === 'category') {
|
|
202
|
-
return {
|
|
203
|
-
...item,
|
|
204
|
-
items: sortSidebarItems(item.items),
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
return item;
|
|
208
|
-
});
|
|
209
|
-
const sortedSidebarItems = lodash_1.orderBy(processedSidebarItems, (item) => item.position, ['asc']);
|
|
210
|
-
return sortedSidebarItems.map(({ position: _removed, ...item }) => item);
|
|
211
|
-
}
|