@docusaurus/plugin-content-docs 2.0.0-beta.12faed89d → 2.0.0-beta.13

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.
Files changed (138) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/categoryGeneratedIndex.d.ts +12 -0
  3. package/lib/categoryGeneratedIndex.js +37 -0
  4. package/lib/cli.d.ts +2 -2
  5. package/lib/cli.js +12 -34
  6. package/lib/client/docsClientUtils.d.ts +0 -3
  7. package/lib/client/docsClientUtils.js +19 -22
  8. package/lib/docFrontMatter.d.ts +1 -1
  9. package/lib/docFrontMatter.js +7 -3
  10. package/lib/docs.d.ts +25 -3
  11. package/lib/docs.js +125 -41
  12. package/lib/globalData.d.ts +1 -1
  13. package/lib/index.d.ts +1 -1
  14. package/lib/index.js +100 -131
  15. package/lib/lastUpdate.js +8 -9
  16. package/lib/markdown/index.d.ts +3 -6
  17. package/lib/markdown/index.js +3 -3
  18. package/lib/markdown/linkify.js +2 -2
  19. package/lib/numberPrefix.d.ts +1 -1
  20. package/lib/options.d.ts +3 -3
  21. package/lib/options.js +48 -11
  22. package/lib/props.d.ts +7 -2
  23. package/lib/props.js +60 -8
  24. package/lib/routes.d.ts +27 -0
  25. package/lib/routes.js +105 -0
  26. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +5 -2
  27. package/lib/sidebars/generator.js +216 -0
  28. package/lib/sidebars/index.d.ts +15 -0
  29. package/lib/sidebars/index.js +73 -0
  30. package/lib/sidebars/normalization.d.ts +14 -0
  31. package/lib/sidebars/normalization.js +77 -0
  32. package/lib/sidebars/processor.d.ts +18 -0
  33. package/lib/sidebars/processor.js +85 -0
  34. package/lib/sidebars/types.d.ts +127 -0
  35. package/lib/sidebars/types.js +8 -0
  36. package/lib/sidebars/utils.d.ts +35 -0
  37. package/lib/sidebars/utils.js +228 -0
  38. package/lib/sidebars/validation.d.ts +10 -0
  39. package/lib/sidebars/validation.js +138 -0
  40. package/lib/slug.d.ts +4 -3
  41. package/lib/slug.js +27 -15
  42. package/lib/tags.d.ts +8 -0
  43. package/lib/tags.js +20 -0
  44. package/lib/theme/hooks/useDocs.js +21 -21
  45. package/lib/translations.d.ts +2 -2
  46. package/lib/translations.js +71 -29
  47. package/lib/types.d.ts +52 -63
  48. package/lib/versions.d.ts +3 -3
  49. package/lib/versions.js +41 -22
  50. package/package.json +20 -20
  51. package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
  52. package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
  53. package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
  54. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  55. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +2 -0
  56. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  57. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  58. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  59. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  60. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  61. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +1 -0
  62. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  63. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +3 -0
  64. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  65. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  66. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +3 -0
  67. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
  68. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
  69. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
  70. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +3 -0
  71. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
  72. package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -73
  73. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  74. package/src/__tests__/__snapshots__/index.test.ts.snap +745 -97
  75. package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -15
  76. package/src/__tests__/cli.test.ts +15 -11
  77. package/src/__tests__/docFrontMatter.test.ts +160 -45
  78. package/src/__tests__/docs.test.ts +311 -150
  79. package/src/__tests__/index.test.ts +108 -66
  80. package/src/__tests__/lastUpdate.test.ts +1 -1
  81. package/src/__tests__/options.test.ts +48 -3
  82. package/src/__tests__/props.test.ts +62 -0
  83. package/src/__tests__/slug.test.ts +127 -20
  84. package/src/__tests__/translations.test.ts +7 -1
  85. package/src/__tests__/versions.test.ts +73 -70
  86. package/src/categoryGeneratedIndex.ts +57 -0
  87. package/src/cli.ts +8 -41
  88. package/src/client/docsClientUtils.ts +14 -26
  89. package/{types.d.ts → src/deps.d.ts} +0 -0
  90. package/src/docFrontMatter.ts +9 -4
  91. package/src/docs.ts +158 -32
  92. package/src/globalData.ts +6 -1
  93. package/src/index.ts +125 -169
  94. package/src/lastUpdate.ts +10 -13
  95. package/src/markdown/index.ts +8 -12
  96. package/src/numberPrefix.ts +5 -3
  97. package/src/options.ts +59 -14
  98. package/src/plugin-content-docs.d.ts +173 -40
  99. package/src/props.ts +90 -15
  100. package/src/routes.ts +173 -0
  101. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  102. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  103. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  104. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  105. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  106. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  107. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  108. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  109. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  110. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  111. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  112. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  113. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  114. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  115. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +36 -6
  116. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +143 -18
  117. package/src/sidebars/__tests__/index.test.ts +204 -0
  118. package/src/sidebars/__tests__/processor.test.ts +237 -0
  119. package/src/sidebars/__tests__/utils.test.ts +695 -0
  120. package/src/sidebars/__tests__/validation.test.ts +105 -0
  121. package/src/sidebars/generator.ts +310 -0
  122. package/src/sidebars/index.ts +94 -0
  123. package/src/sidebars/normalization.ts +112 -0
  124. package/src/sidebars/processor.ts +154 -0
  125. package/src/sidebars/types.ts +211 -0
  126. package/src/sidebars/utils.ts +329 -0
  127. package/src/sidebars/validation.ts +168 -0
  128. package/src/slug.ts +32 -17
  129. package/src/tags.ts +19 -0
  130. package/src/translations.ts +103 -47
  131. package/src/types.ts +64 -107
  132. package/src/versions.ts +59 -25
  133. package/lib/sidebarItemsGenerator.js +0 -211
  134. package/lib/sidebars.d.ts +0 -43
  135. package/lib/sidebars.js +0 -320
  136. package/src/__tests__/sidebars.test.ts +0 -639
  137. package/src/sidebarItemsGenerator.ts +0 -307
  138. package/src/sidebars.ts +0 -522
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,9 +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;
33
- versionBanner: VersionBanner;
35
+ versionBanner: VersionBanner | null;
36
+ versionBadge: boolean;
37
+ versionClassName: string;
34
38
  isLast: boolean;
35
39
  sidebarFilePath: string | false | undefined; // versioned_sidebars/1.0.0.json
36
40
  routePriority: number | undefined; // -1 for the latest docs
@@ -46,7 +50,6 @@ export type EditUrlFunction = (editUrlParams: {
46
50
 
47
51
  export type MetadataOptions = {
48
52
  routeBasePath: string;
49
- homePageId?: string;
50
53
  editUrl?: string | EditUrlFunction;
51
54
  editCurrentVersion: boolean;
52
55
  editLocalizedFiles: boolean;
@@ -61,12 +64,14 @@ export type PathOptions = {
61
64
  };
62
65
 
63
66
  // TODO support custom version banner? {type: "error", content: "html content"}
64
- export type VersionBanner = 'none' | 'unreleased' | 'unmaintained';
67
+ export type VersionBanner = 'unreleased' | 'unmaintained';
65
68
 
66
69
  export type VersionOptions = {
67
70
  path?: string;
68
71
  label?: string;
69
- banner?: VersionBanner;
72
+ banner?: 'none' | VersionBanner;
73
+ badge?: boolean;
74
+ className?: string;
70
75
  };
71
76
 
72
77
  export type VersionsOptions = {
@@ -75,110 +80,36 @@ export type VersionsOptions = {
75
80
  onlyIncludeVersions?: string[];
76
81
  };
77
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
+
78
93
  export type PluginOptions = MetadataOptions &
79
94
  PathOptions &
80
95
  VersionsOptions &
81
- RemarkAndRehypePluginOptions & {
96
+ RemarkAndRehypePluginOptions &
97
+ SidebarOptions & {
82
98
  id: string;
83
99
  include: string[];
100
+ exclude: string[];
84
101
  docLayoutComponent: string;
85
102
  docItemComponent: string;
103
+ docTagDocListComponent: string;
104
+ docTagsListComponent: string;
105
+ docCategoryGeneratedIndexComponent: string;
86
106
  admonitions: Record<string, unknown>;
87
107
  disableVersioning: boolean;
88
108
  includeCurrentVersion: boolean;
89
109
  sidebarItemsGenerator: SidebarItemsGeneratorOption;
110
+ tagsBasePath: string;
90
111
  };
91
112
 
92
- export type SidebarItemBase = {
93
- customProps?: Record<string, unknown>;
94
- };
95
-
96
- export type SidebarItemDoc = SidebarItemBase & {
97
- type: 'doc' | 'ref';
98
- label?: string;
99
- id: string;
100
- };
101
-
102
- export type SidebarItemLink = SidebarItemBase & {
103
- type: 'link';
104
- href: string;
105
- label: string;
106
- };
107
-
108
- export type SidebarItemCategory = SidebarItemBase & {
109
- type: 'category';
110
- label: string;
111
- items: SidebarItem[];
112
- collapsed: boolean;
113
- };
114
-
115
- export type UnprocessedSidebarItemAutogenerated = {
116
- type: 'autogenerated';
117
- dirName: string;
118
- };
119
-
120
- export type UnprocessedSidebarItemCategory = SidebarItemBase & {
121
- type: 'category';
122
- label: string;
123
- items: UnprocessedSidebarItem[];
124
- collapsed: boolean;
125
- };
126
-
127
- export type UnprocessedSidebarItem =
128
- | SidebarItemDoc
129
- | SidebarItemLink
130
- | UnprocessedSidebarItemCategory
131
- | UnprocessedSidebarItemAutogenerated;
132
-
133
- export type UnprocessedSidebar = UnprocessedSidebarItem[];
134
- export type UnprocessedSidebars = Record<string, UnprocessedSidebar>;
135
-
136
- export type SidebarItem =
137
- | SidebarItemDoc
138
- | SidebarItemLink
139
- | SidebarItemCategory;
140
-
141
- export type Sidebar = SidebarItem[];
142
- export type SidebarItemType = SidebarItem['type'];
143
- export type Sidebars = Record<string, Sidebar>;
144
-
145
- // Reduce API surface for options.sidebarItemsGenerator
146
- // The user-provided generator fn should receive only a subset of metadatas
147
- // A change to any of these metadatas can be considered as a breaking change
148
- export type SidebarItemsGeneratorDoc = Pick<
149
- DocMetadataBase,
150
- 'id' | 'frontMatter' | 'source' | 'sourceDirName' | 'sidebarPosition'
151
- >;
152
- export type SidebarItemsGeneratorVersion = Pick<
153
- VersionMetadata,
154
- 'versionName' | 'contentPath'
155
- >;
156
-
157
- export type SidebarItemsGeneratorArgs = {
158
- item: UnprocessedSidebarItemAutogenerated;
159
- version: SidebarItemsGeneratorVersion;
160
- docs: SidebarItemsGeneratorDoc[];
161
- numberPrefixParser: NumberPrefixParser;
162
- };
163
- export type SidebarItemsGenerator = (
164
- generatorArgs: SidebarItemsGeneratorArgs,
165
- ) => Promise<SidebarItem[]>;
166
-
167
- // Also inject the default generator to conveniently wrap/enhance/sort the default sidebar gen logic
168
- // see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
169
- export type SidebarItemsGeneratorOptionArgs = {
170
- defaultSidebarItemsGenerator: SidebarItemsGenerator;
171
- } & SidebarItemsGeneratorArgs;
172
- export type SidebarItemsGeneratorOption = (
173
- generatorArgs: SidebarItemsGeneratorOptionArgs,
174
- ) => Promise<SidebarItem[]>;
175
-
176
- export type OrderMetadata = {
177
- previous?: string;
178
- next?: string;
179
- sidebar?: string;
180
- };
181
-
182
113
  export type LastUpdateData = {
183
114
  lastUpdatedAt?: number;
184
115
  formattedLastUpdatedAt?: string;
@@ -187,9 +118,9 @@ export type LastUpdateData = {
187
118
 
188
119
  export type DocFrontMatter = {
189
120
  // Front matter uses snake case
190
- /* eslint-disable camelcase */
191
121
  id?: string;
192
122
  title?: string;
123
+ tags?: FrontMatterTag[];
193
124
  hide_title?: boolean;
194
125
  hide_table_of_contents?: boolean;
195
126
  keywords?: string[];
@@ -198,25 +129,29 @@ export type DocFrontMatter = {
198
129
  slug?: string;
199
130
  sidebar_label?: string;
200
131
  sidebar_position?: number;
132
+ sidebar_class_name?: string;
201
133
  pagination_label?: string;
202
134
  custom_edit_url?: string | null;
203
135
  parse_number_prefixes?: boolean;
204
- /* eslint-enable camelcase */
136
+ toc_min_heading_level?: number;
137
+ toc_max_heading_level?: number;
138
+ pagination_next?: string | null;
139
+ pagination_prev?: string | null;
205
140
  };
206
141
 
207
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"
208
145
  version: VersionName;
209
- unversionedId: string;
210
- id: string;
211
- isDocsHomePage: boolean;
212
146
  title: string;
213
147
  description: string;
214
- source: string;
215
- 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"
216
150
  slug: string;
217
151
  permalink: string;
218
152
  sidebarPosition?: number;
219
153
  editUrl?: string | null;
154
+ tags: Tag[];
220
155
  frontMatter: DocFrontMatter & Record<string, unknown>;
221
156
  };
222
157
 
@@ -231,14 +166,35 @@ export type DocMetadata = DocMetadataBase & {
231
166
  next?: DocNavLink;
232
167
  };
233
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
+
234
179
  export type SourceToPermalink = {
235
180
  [source: string]: string;
236
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
+
237
192
  export type LoadedVersion = VersionMetadata & {
238
193
  versionPath: string;
239
194
  mainDocId: string;
240
195
  docs: DocMetadata[];
241
196
  sidebars: Sidebars;
197
+ categoryGeneratedIndices: CategoryGeneratedIndexMetadata[];
242
198
  };
243
199
 
244
200
  export type LoadedContent = {
@@ -274,6 +230,7 @@ export type DocsMarkdownOption = {
274
230
  onBrokenMarkdownLink: (brokenMarkdownLink: BrokenMarkdownLink) => void;
275
231
  };
276
232
 
277
- export type NumberPrefixParser = (
278
- filename: string,
279
- ) => {filename: string; numberPrefix?: number};
233
+ export type NumberPrefixParser = (filename: string) => {
234
+ filename: string;
235
+ numberPrefix?: number;
236
+ };
package/src/versions.ts CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  import path from 'path';
9
9
  import fs from 'fs-extra';
10
- import {
10
+ import type {
11
11
  PluginOptions,
12
12
  VersionBanner,
13
13
  VersionMetadata,
@@ -21,9 +21,13 @@ import {
21
21
  CURRENT_VERSION_NAME,
22
22
  } from './constants';
23
23
 
24
- import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
25
- import {LoadContext} from '@docusaurus/types';
26
- import {getPluginI18nPath, normalizeUrl, posixPath} from '@docusaurus/utils';
24
+ import type {LoadContext} from '@docusaurus/types';
25
+ import {
26
+ getPluginI18nPath,
27
+ normalizeUrl,
28
+ posixPath,
29
+ DEFAULT_PLUGIN_ID,
30
+ } from '@docusaurus/utils';
27
31
  import {difference} from 'lodash';
28
32
  import {resolveSidebarPathOption} from './sidebars';
29
33
 
@@ -264,10 +268,10 @@ function getDefaultVersionBanner({
264
268
  versionName: string;
265
269
  versionNames: string[];
266
270
  lastVersionName: string;
267
- }): VersionBanner {
271
+ }): VersionBanner | null {
268
272
  // Current version: good, no banner
269
273
  if (versionName === lastVersionName) {
270
- return 'none';
274
+ return null;
271
275
  }
272
276
  // Upcoming versions: unreleased banner
273
277
  else if (
@@ -291,17 +295,45 @@ function getVersionBanner({
291
295
  versionNames: string[];
292
296
  lastVersionName: string;
293
297
  options: Pick<PluginOptions, 'versions'>;
294
- }): VersionBanner {
295
- const versionOptionBanner = options.versions[versionName]?.banner;
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
+ }
296
309
 
297
- return (
298
- versionOptionBanner ??
299
- getDefaultVersionBanner({
300
- versionName,
301
- versionNames,
302
- lastVersionName,
303
- })
304
- );
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;
305
337
  }
306
338
 
307
339
  function createVersionMetadata({
@@ -321,20 +353,14 @@ function createVersionMetadata({
321
353
  | 'path'
322
354
  | 'sidebarPath'
323
355
  | 'routeBasePath'
356
+ | 'tagsBasePath'
324
357
  | 'versions'
325
358
  | 'editUrl'
326
359
  | 'editCurrentVersion'
327
360
  >;
328
361
  }): VersionMetadata {
329
- const {
330
- sidebarFilePath,
331
- contentPath,
332
- contentPathLocalized,
333
- } = getVersionMetadataPaths({
334
- versionName,
335
- context,
336
- options,
337
- });
362
+ const {sidebarFilePath, contentPath, contentPathLocalized} =
363
+ getVersionMetadataPaths({versionName, context, options});
338
364
 
339
365
  const isLast = versionName === lastVersionName;
340
366
 
@@ -370,10 +396,15 @@ function createVersionMetadata({
370
396
  // Because /docs/:route` should always be after `/docs/versionName/:route`.
371
397
  const routePriority = versionPathPart === '' ? -1 : undefined;
372
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
+
373
403
  return {
374
404
  versionName,
375
405
  versionLabel,
376
406
  versionPath,
407
+ tagsPath,
377
408
  versionEditUrl: versionEditUrls?.versionEditUrl,
378
409
  versionEditUrlLocalized: versionEditUrls?.versionEditUrlLocalized,
379
410
  versionBanner: getVersionBanner({
@@ -382,6 +413,8 @@ function createVersionMetadata({
382
413
  lastVersionName,
383
414
  options,
384
415
  }),
416
+ versionBadge: getVersionBadge({versionName, versionNames, options}),
417
+ versionClassName: getVersionClassName({versionName, options}),
385
418
  isLast,
386
419
  routePriority,
387
420
  sidebarFilePath,
@@ -526,6 +559,7 @@ export function readVersionsMetadata({
526
559
  | 'path'
527
560
  | 'sidebarPath'
528
561
  | 'routeBasePath'
562
+ | 'tagsBasePath'
529
563
  | 'includeCurrentVersion'
530
564
  | 'disableVersioning'
531
565
  | 'lastVersion'
@@ -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
- }
package/lib/sidebars.d.ts DELETED
@@ -1,43 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
- import { Sidebars, SidebarItem, SidebarItemLink, SidebarItemDoc, Sidebar, SidebarItemCategory, UnprocessedSidebars, UnprocessedSidebar, DocMetadataBase, VersionMetadata, SidebarItemsGeneratorDoc, SidebarItemsGeneratorVersion, NumberPrefixParser, SidebarItemsGeneratorOption, PluginOptions } from './types';
8
- export declare const DefaultCategoryCollapsedValue = true;
9
- export declare const DefaultSidebars: UnprocessedSidebars;
10
- export declare const DisabledSidebars: UnprocessedSidebars;
11
- export declare function resolveSidebarPathOption(siteDir: string, sidebarPathOption: PluginOptions['sidebarPath']): PluginOptions['sidebarPath'];
12
- export declare function loadSidebars(sidebarFilePath: string | false | undefined): UnprocessedSidebars;
13
- export declare function toSidebarItemsGeneratorDoc(doc: DocMetadataBase): SidebarItemsGeneratorDoc;
14
- export declare function toSidebarItemsGeneratorVersion(version: VersionMetadata): SidebarItemsGeneratorVersion;
15
- export declare function processSidebar({ sidebarItemsGenerator, numberPrefixParser, unprocessedSidebar, docs, version, }: {
16
- sidebarItemsGenerator: SidebarItemsGeneratorOption;
17
- numberPrefixParser: NumberPrefixParser;
18
- unprocessedSidebar: UnprocessedSidebar;
19
- docs: DocMetadataBase[];
20
- version: VersionMetadata;
21
- }): Promise<Sidebar>;
22
- export declare function processSidebars({ sidebarItemsGenerator, numberPrefixParser, unprocessedSidebars, docs, version, }: {
23
- sidebarItemsGenerator: SidebarItemsGeneratorOption;
24
- numberPrefixParser: NumberPrefixParser;
25
- unprocessedSidebars: UnprocessedSidebars;
26
- docs: DocMetadataBase[];
27
- version: VersionMetadata;
28
- }): Promise<Sidebars>;
29
- export declare function collectSidebarDocItems(sidebar: Sidebar): SidebarItemDoc[];
30
- export declare function collectSidebarCategories(sidebar: Sidebar): SidebarItemCategory[];
31
- export declare function collectSidebarLinks(sidebar: Sidebar): SidebarItemLink[];
32
- export declare function transformSidebarItems(sidebar: Sidebar, updateFn: (item: SidebarItem) => SidebarItem): Sidebar;
33
- export declare function collectSidebarsDocIds(sidebars: Sidebars): Record<string, string[]>;
34
- export declare function createSidebarsUtils(sidebars: Sidebars): {
35
- getFirstDocIdOfFirstSidebar: () => string | undefined;
36
- getSidebarNameByDocId: (docId: string) => string | undefined;
37
- getDocNavigation: (docId: string) => {
38
- sidebarName: string | undefined;
39
- previousId: string | undefined;
40
- nextId: string | undefined;
41
- };
42
- checkSidebarsDocIds: (validDocIds: string[], sidebarFilePath: string) => void;
43
- };