@docusaurus/plugin-content-docs 2.0.0-beta.8e9b829d9 → 2.0.0-beta.9

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 (103) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/cli.d.ts +1 -1
  3. package/lib/cli.js +18 -23
  4. package/lib/client/docsClientUtils.d.ts +0 -3
  5. package/lib/client/docsClientUtils.js +10 -7
  6. package/lib/docFrontMatter.js +6 -2
  7. package/lib/docs.d.ts +3 -1
  8. package/lib/docs.js +76 -25
  9. package/lib/index.js +70 -77
  10. package/lib/lastUpdate.js +4 -4
  11. package/lib/markdown/index.d.ts +3 -6
  12. package/lib/markdown/index.js +3 -3
  13. package/lib/markdown/linkify.js +2 -2
  14. package/lib/options.js +12 -4
  15. package/lib/props.d.ts +7 -2
  16. package/lib/props.js +26 -3
  17. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +2 -1
  18. package/lib/sidebars/generator.js +174 -0
  19. package/lib/sidebars/index.d.ts +14 -0
  20. package/lib/sidebars/index.js +64 -0
  21. package/lib/sidebars/normalization.d.ts +9 -0
  22. package/lib/sidebars/normalization.js +58 -0
  23. package/lib/sidebars/processor.d.ts +16 -0
  24. package/lib/sidebars/processor.js +70 -0
  25. package/lib/sidebars/types.d.ts +87 -0
  26. package/lib/sidebars/types.js +13 -0
  27. package/lib/sidebars/utils.d.ts +22 -0
  28. package/lib/sidebars/utils.js +101 -0
  29. package/lib/sidebars/validation.d.ts +8 -0
  30. package/lib/sidebars/validation.js +102 -0
  31. package/lib/slug.js +4 -4
  32. package/lib/tags.d.ts +8 -0
  33. package/lib/tags.js +22 -0
  34. package/lib/theme/hooks/useDocs.js +21 -21
  35. package/lib/translations.d.ts +1 -1
  36. package/lib/translations.js +13 -13
  37. package/lib/types.d.ts +29 -61
  38. package/lib/versions.d.ts +1 -1
  39. package/lib/versions.js +40 -20
  40. package/package.json +15 -14
  41. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  42. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +1 -0
  43. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  44. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  45. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  46. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  47. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  48. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  49. package/src/__tests__/__snapshots__/cli.test.ts.snap +28 -0
  50. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  51. package/src/__tests__/__snapshots__/index.test.ts.snap +426 -25
  52. package/src/__tests__/docFrontMatter.test.ts +160 -45
  53. package/src/__tests__/docs.test.ts +167 -21
  54. package/src/__tests__/index.test.ts +53 -27
  55. package/src/__tests__/options.test.ts +4 -1
  56. package/src/__tests__/props.test.ts +62 -0
  57. package/src/__tests__/versions.test.ts +68 -63
  58. package/src/cli.ts +23 -30
  59. package/src/client/docsClientUtils.ts +1 -12
  60. package/src/docFrontMatter.ts +7 -2
  61. package/src/docs.ts +88 -9
  62. package/src/index.ts +77 -91
  63. package/src/markdown/index.ts +8 -12
  64. package/src/numberPrefix.ts +4 -2
  65. package/src/options.ts +13 -1
  66. package/src/plugin-content-docs.d.ts +107 -32
  67. package/src/props.ts +41 -5
  68. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  69. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  70. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  71. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  72. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  73. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  74. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  75. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  76. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  77. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  78. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  79. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  80. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  81. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  82. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +6 -6
  83. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +2 -2
  84. package/src/sidebars/__tests__/index.test.ts +202 -0
  85. package/src/sidebars/__tests__/processor.test.ts +148 -0
  86. package/src/sidebars/__tests__/utils.test.ts +395 -0
  87. package/src/sidebars/generator.ts +253 -0
  88. package/src/sidebars/index.ts +84 -0
  89. package/src/sidebars/normalization.ts +88 -0
  90. package/src/sidebars/processor.ts +124 -0
  91. package/src/sidebars/types.ts +156 -0
  92. package/src/sidebars/utils.ts +146 -0
  93. package/src/sidebars/validation.ts +124 -0
  94. package/src/tags.ts +21 -0
  95. package/src/translations.ts +26 -36
  96. package/src/types.ts +35 -101
  97. package/src/versions.ts +51 -21
  98. package/lib/sidebarItemsGenerator.js +0 -215
  99. package/lib/sidebars.d.ts +0 -45
  100. package/lib/sidebars.js +0 -354
  101. package/src/__tests__/sidebars.test.ts +0 -746
  102. package/src/sidebarItemsGenerator.ts +0 -315
  103. package/src/sidebars.ts +0 -589
package/src/index.ts CHANGED
@@ -21,8 +21,9 @@ import {
21
21
  createAbsoluteFilePathMatcher,
22
22
  } from '@docusaurus/utils';
23
23
  import {LoadContext, Plugin, RouteConfig} from '@docusaurus/types';
24
- import {loadSidebars, createSidebarsUtils, processSidebars} from './sidebars';
25
- import {readVersionDocs, processDocMetadata} from './docs';
24
+ import {loadSidebars} from './sidebars';
25
+ import {CategoryMetadataFilenamePattern} from './sidebars/generator';
26
+ import {readVersionDocs, processDocMetadata, handleNavigation} from './docs';
26
27
  import {getDocsDirPaths, readVersionsMetadata} from './versions';
27
28
 
28
29
  import {
@@ -33,23 +34,24 @@ import {
33
34
  DocMetadata,
34
35
  GlobalPluginData,
35
36
  VersionMetadata,
36
- DocNavLink,
37
37
  LoadedVersion,
38
38
  DocFile,
39
39
  DocsMarkdownOption,
40
+ VersionTag,
40
41
  } from './types';
41
42
  import {RuleSetRule} from 'webpack';
42
43
  import {cliDocsVersionCommand} from './cli';
43
44
  import {VERSIONS_JSON_FILE} from './constants';
44
- import {flatten, keyBy, compact, mapValues} from 'lodash';
45
+ import {keyBy, mapValues} from 'lodash';
45
46
  import {toGlobalDataVersion} from './globalData';
46
- import {toVersionMetadataProp} from './props';
47
+ import {toTagDocListProp, toVersionMetadataProp} from './props';
47
48
  import {
48
49
  translateLoadedContent,
49
50
  getLoadedContentTranslationFiles,
50
51
  } from './translations';
51
- import {CategoryMetadataFilenamePattern} from './sidebarItemsGenerator';
52
52
  import chalk from 'chalk';
53
+ import {getVersionTags} from './tags';
54
+ import {PropTagsListPage} from '@docusaurus/plugin-content-docs-types';
53
55
 
54
56
  export default function pluginContentDocs(
55
57
  context: LoadContext,
@@ -113,11 +115,9 @@ export default function pluginContentDocs(
113
115
  getPathsToWatch() {
114
116
  function getVersionPathsToWatch(version: VersionMetadata): string[] {
115
117
  const result = [
116
- ...flatten(
117
- options.include.map((pattern) =>
118
- getDocsDirPaths(version).map(
119
- (docsDirPath) => `${docsDirPath}/${pattern}`,
120
- ),
118
+ ...options.include.flatMap((pattern) =>
119
+ getDocsDirPaths(version).map(
120
+ (docsDirPath) => `${docsDirPath}/${pattern}`,
121
121
  ),
122
122
  ),
123
123
  `${version.contentPath}/**/${CategoryMetadataFilenamePattern}`,
@@ -128,7 +128,7 @@ export default function pluginContentDocs(
128
128
  return result;
129
129
  }
130
130
 
131
- return flatten(versionsMetadata.map(getVersionPathsToWatch));
131
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
132
132
  },
133
133
 
134
134
  async loadContent() {
@@ -160,26 +160,13 @@ export default function pluginContentDocs(
160
160
  async function doLoadVersion(
161
161
  versionMetadata: VersionMetadata,
162
162
  ): Promise<LoadedVersion> {
163
- const unprocessedSidebars = loadSidebars(
164
- versionMetadata.sidebarFilePath,
165
- {
166
- sidebarCollapsed: options.sidebarCollapsed,
167
- sidebarCollapsible: options.sidebarCollapsible,
168
- },
169
- );
170
-
171
163
  const docsBase: DocMetadataBase[] = await loadVersionDocsBase(
172
164
  versionMetadata,
173
165
  );
174
- const docsBaseById: Record<string, DocMetadataBase> = keyBy(
175
- docsBase,
176
- (doc) => doc.id,
177
- );
178
166
 
179
- const sidebars = await processSidebars({
167
+ const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
180
168
  sidebarItemsGenerator: options.sidebarItemsGenerator,
181
169
  numberPrefixParser: options.numberPrefixParser,
182
- unprocessedSidebars,
183
170
  docs: docsBase,
184
171
  version: versionMetadata,
185
172
  options: {
@@ -187,70 +174,14 @@ export default function pluginContentDocs(
187
174
  sidebarCollapsible: options.sidebarCollapsible,
188
175
  },
189
176
  });
190
-
191
- const sidebarsUtils = createSidebarsUtils(sidebars);
192
-
193
- const validDocIds = Object.keys(docsBaseById);
194
- sidebarsUtils.checkSidebarsDocIds(
195
- validDocIds,
196
- versionMetadata.sidebarFilePath as string,
197
- );
198
-
199
- // Add sidebar/next/previous to the docs
200
- function addNavData(doc: DocMetadataBase): DocMetadata {
201
- const {
202
- sidebarName,
203
- previousId,
204
- nextId,
205
- } = sidebarsUtils.getDocNavigation(doc.id);
206
- const toDocNavLink = (navDocId: string): DocNavLink => {
207
- const {title, permalink, frontMatter} = docsBaseById[navDocId];
208
- return {
209
- title:
210
- frontMatter.pagination_label ??
211
- frontMatter.sidebar_label ??
212
- title,
213
- permalink,
214
- };
215
- };
216
- return {
217
- ...doc,
218
- sidebar: sidebarName,
219
- previous: previousId ? toDocNavLink(previousId) : undefined,
220
- next: nextId ? toDocNavLink(nextId) : undefined,
221
- };
222
- }
223
-
224
- const docs = docsBase.map(addNavData);
225
-
226
- // sort to ensure consistent output for tests
227
- docs.sort((a, b) => a.id.localeCompare(b.id));
228
-
229
- // The "main doc" is the "version entry point"
230
- // We browse this doc by clicking on a version:
231
- // - the "home" doc (at '/docs/')
232
- // - the first doc of the first sidebar
233
- // - a random doc (if no docs are in any sidebar... edge case)
234
- function getMainDoc(): DocMetadata {
235
- const versionHomeDoc = docs.find(
236
- (doc) =>
237
- doc.unversionedId === options.homePageId || doc.slug === '/',
238
- );
239
- const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
240
- if (versionHomeDoc) {
241
- return versionHomeDoc;
242
- } else if (firstDocIdOfFirstSidebar) {
243
- return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar)!;
244
- } else {
245
- return docs[0];
246
- }
247
- }
248
-
249
177
  return {
250
178
  ...versionMetadata,
251
- mainDocId: getMainDoc().unversionedId,
179
+ ...handleNavigation(
180
+ docsBase,
181
+ sidebars,
182
+ versionMetadata.sidebarFilePath as string,
183
+ ),
252
184
  sidebars,
253
- docs: docs.map(addNavData),
254
185
  };
255
186
  }
256
187
 
@@ -314,9 +245,64 @@ export default function pluginContentDocs(
314
245
  return routes.sort((a, b) => a.path.localeCompare(b.path));
315
246
  };
316
247
 
248
+ async function createVersionTagsRoutes(loadedVersion: LoadedVersion) {
249
+ const versionTags = getVersionTags(loadedVersion.docs);
250
+
251
+ async function createTagsListPage() {
252
+ const tagsProp: PropTagsListPage['tags'] = Object.values(
253
+ versionTags,
254
+ ).map((tagValue) => ({
255
+ name: tagValue.name,
256
+ permalink: tagValue.permalink,
257
+ count: tagValue.docIds.length,
258
+ }));
259
+
260
+ // Only create /tags page if there are tags.
261
+ if (Object.keys(tagsProp).length > 0) {
262
+ const tagsPropPath = await createData(
263
+ `${docuHash(`tags-list-${loadedVersion.versionName}-prop`)}.json`,
264
+ JSON.stringify(tagsProp, null, 2),
265
+ );
266
+ addRoute({
267
+ path: loadedVersion.tagsPath,
268
+ exact: true,
269
+ component: options.docTagsListComponent,
270
+ modules: {
271
+ tags: aliasedSource(tagsPropPath),
272
+ },
273
+ });
274
+ }
275
+ }
276
+
277
+ async function createTagDocListPage(tag: VersionTag) {
278
+ const tagProps = toTagDocListProp({
279
+ allTagsPath: loadedVersion.tagsPath,
280
+ tag,
281
+ docs: loadedVersion.docs,
282
+ });
283
+ const tagPropPath = await createData(
284
+ `${docuHash(`tag-${tag.permalink}`)}.json`,
285
+ JSON.stringify(tagProps, null, 2),
286
+ );
287
+ addRoute({
288
+ path: tag.permalink,
289
+ component: options.docTagDocListComponent,
290
+ exact: true,
291
+ modules: {
292
+ tag: aliasedSource(tagPropPath),
293
+ },
294
+ });
295
+ }
296
+
297
+ await createTagsListPage();
298
+ await Promise.all(Object.values(versionTags).map(createTagDocListPage));
299
+ }
300
+
317
301
  async function doCreateVersionRoutes(
318
302
  loadedVersion: LoadedVersion,
319
303
  ): Promise<void> {
304
+ await createVersionTagsRoutes(loadedVersion);
305
+
320
306
  const versionMetadata = toVersionMetadataProp(pluginId, loadedVersion);
321
307
  const versionMetadataPropPath = await createData(
322
308
  `${docuHash(
@@ -373,7 +359,7 @@ export default function pluginContentDocs(
373
359
  } = options;
374
360
 
375
361
  function getSourceToPermalink(): SourceToPermalink {
376
- const allDocs = flatten(content.loadedVersions.map((v) => v.docs));
362
+ const allDocs = content.loadedVersions.flatMap((v) => v.docs);
377
363
  return mapValues(
378
364
  keyBy(allDocs, (d) => d.source),
379
365
  (d) => d.permalink,
@@ -396,13 +382,13 @@ export default function pluginContentDocs(
396
382
  };
397
383
 
398
384
  function createMDXLoaderRule(): RuleSetRule {
399
- const contentDirs = flatten(versionsMetadata.map(getDocsDirPaths));
385
+ const contentDirs = versionsMetadata.flatMap(getDocsDirPaths);
400
386
  return {
401
387
  test: /(\.mdx?)$/,
402
388
  include: contentDirs
403
389
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
404
390
  .map(addTrailingPathSeparator),
405
- use: compact([
391
+ use: [
406
392
  getJSLoader({isServer}),
407
393
  {
408
394
  loader: require.resolve('@docusaurus/mdx-loader'),
@@ -428,7 +414,7 @@ export default function pluginContentDocs(
428
414
  loader: path.resolve(__dirname, './markdown/index.js'),
429
415
  options: docsMarkdownOptions,
430
416
  },
431
- ]),
417
+ ].filter(Boolean),
432
418
  };
433
419
  }
434
420
 
@@ -7,20 +7,16 @@
7
7
 
8
8
  import {linkify} from './linkify';
9
9
  import {DocsMarkdownOption} from '../types';
10
+ import type {LoaderContext} from 'webpack';
10
11
 
11
- // TODO temporary until Webpack5 export this type
12
- // see https://github.com/webpack/webpack/issues/11630
13
- interface Loader extends Function {
14
- (this: any, source: string): string | Buffer | void | undefined;
15
- }
16
-
17
- const markdownLoader: Loader = function (source) {
18
- const fileString = source as string;
12
+ export default function markdownLoader(
13
+ this: LoaderContext<DocsMarkdownOption>,
14
+ source: string,
15
+ ): void {
16
+ const fileString = source;
19
17
  const callback = this.async();
20
- const options = this.getOptions() as DocsMarkdownOption;
18
+ const options = this.getOptions();
21
19
  return (
22
20
  callback && callback(null, linkify(fileString, this.resourcePath, options))
23
21
  );
24
- };
25
-
26
- export default markdownLoader;
22
+ }
@@ -10,7 +10,8 @@ import {NumberPrefixParser} from './types';
10
10
  // Best-effort to avoid parsing some patterns as number prefix
11
11
  const IgnoredPrefixPatterns = (function () {
12
12
  // ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640
13
- const DateLikePrefixRegex = /^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/;
13
+ const DateLikePrefixRegex =
14
+ /^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/;
14
15
 
15
16
  // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
16
17
  // note: we could try to parse float numbers in filenames but that is probably not worth it
@@ -23,7 +24,8 @@ const IgnoredPrefixPatterns = (function () {
23
24
  );
24
25
  })();
25
26
 
26
- const NumberPrefixRegex = /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
27
+ const NumberPrefixRegex =
28
+ /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
27
29
 
28
30
  // 0-myDoc => {filename: myDoc, numberPrefix: 0}
29
31
  // 003 - myDoc => {filename: myDoc, numberPrefix: 3}
package/src/options.ts CHANGED
@@ -17,7 +17,7 @@ import {GlobExcludeDefault} from '@docusaurus/utils';
17
17
  import {OptionValidationContext, ValidationResult} from '@docusaurus/types';
18
18
  import chalk from 'chalk';
19
19
  import admonitions from 'remark-admonitions';
20
- import {DefaultSidebarItemsGenerator} from './sidebarItemsGenerator';
20
+ import {DefaultSidebarItemsGenerator} from './sidebars/generator';
21
21
  import {
22
22
  DefaultNumberPrefixParser,
23
23
  DisabledNumberPrefixParser,
@@ -26,6 +26,7 @@ import {
26
26
  export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
27
27
  path: 'docs', // Path to data on filesystem, relative to site dir.
28
28
  routeBasePath: 'docs', // URL Route.
29
+ tagsBasePath: 'tags', // URL Tags Route.
29
30
  homePageId: undefined, // TODO remove soon, deprecated
30
31
  include: ['**/*.{md,mdx}'], // Extensions to include.
31
32
  exclude: GlobExcludeDefault,
@@ -33,6 +34,8 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'> = {
33
34
  numberPrefixParser: DefaultNumberPrefixParser,
34
35
  docLayoutComponent: '@theme/DocPage',
35
36
  docItemComponent: '@theme/DocItem',
37
+ docTagDocListComponent: '@theme/DocTagDocListPage',
38
+ docTagsListComponent: '@theme/DocTagsListPage',
36
39
  remarkPlugins: [],
37
40
  rehypePlugins: [],
38
41
  beforeDefaultRemarkPlugins: [],
@@ -54,6 +57,8 @@ const VersionOptionsSchema = Joi.object({
54
57
  path: Joi.string().allow('').optional(),
55
58
  label: Joi.string().optional(),
56
59
  banner: Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
60
+ badge: Joi.boolean().optional(),
61
+ className: Joi.string().optional(),
57
62
  });
58
63
 
59
64
  const VersionsOptionsSchema = Joi.object()
@@ -69,6 +74,7 @@ export const OptionsSchema = Joi.object({
69
74
  // '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
70
75
  // .allow('') ""
71
76
  .default(DEFAULT_OPTIONS.routeBasePath),
77
+ tagsBasePath: Joi.string().default(DEFAULT_OPTIONS.tagsBasePath),
72
78
  homePageId: Joi.string().optional(),
73
79
  include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
74
80
  exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
@@ -94,6 +100,12 @@ export const OptionsSchema = Joi.object({
94
100
  .default(() => DEFAULT_OPTIONS.numberPrefixParser),
95
101
  docLayoutComponent: Joi.string().default(DEFAULT_OPTIONS.docLayoutComponent),
96
102
  docItemComponent: Joi.string().default(DEFAULT_OPTIONS.docItemComponent),
103
+ docTagsListComponent: Joi.string().default(
104
+ DEFAULT_OPTIONS.docTagsListComponent,
105
+ ),
106
+ docTagDocListComponent: Joi.string().default(
107
+ DEFAULT_OPTIONS.docTagDocListComponent,
108
+ ),
97
109
  remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
98
110
  rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),
99
111
  beforeDefaultRemarkPlugins: RemarkPluginsSchema.default(
@@ -5,47 +5,57 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- /* eslint-disable camelcase */
8
+ declare module '@docusaurus/plugin-content-docs' {
9
+ export type Options = Partial<import('./types').PluginOptions>;
10
+ export type SidebarsConfig = import('./sidebars/types').SidebarsConfig;
11
+ }
9
12
 
13
+ // TODO public api surface types should rather be exposed as "@docusaurus/plugin-content-docs"
10
14
  declare module '@docusaurus/plugin-content-docs-types' {
11
- type VersionBanner = import('./types').VersionBanner;
15
+ export type VersionBanner = import('./types').VersionBanner;
12
16
  type GlobalDataVersion = import('./types').GlobalVersion;
13
17
  type GlobalDataDoc = import('./types').GlobalDoc;
18
+ type VersionTag = import('./types').VersionTag;
19
+
20
+ export type {GlobalDataVersion, GlobalDataDoc};
14
21
 
15
22
  export type PropVersionMetadata = {
16
23
  pluginId: string;
17
24
  version: string;
18
25
  label: string;
19
- banner: VersionBanner;
26
+ banner: VersionBanner | null;
27
+ badge: boolean;
28
+ className: string;
20
29
  isLast: boolean;
21
30
  docsSidebars: PropSidebars;
22
31
  };
23
32
 
24
- type PropsSidebarItemBase = {
25
- customProps?: Record<string, unknown>;
33
+ export type PropSidebarItemLink = import('./sidebars/types').SidebarItemLink;
34
+ export type PropSidebarItemCategory =
35
+ import('./sidebars/types').PropSidebarItemCategory;
36
+ export type PropSidebarItem = import('./sidebars/types').PropSidebarItem;
37
+ export type PropSidebars = import('./sidebars/types').PropSidebars;
38
+
39
+ export type PropTagDocListDoc = {
40
+ id: string;
41
+ title: string;
42
+ description: string;
43
+ permalink: string;
26
44
  };
27
-
28
- export type PropSidebarItemLink = PropsSidebarItemBase & {
29
- type: 'link';
30
- href: string;
31
- label: string;
32
- };
33
-
34
- export type PropSidebarItemCategory = PropsSidebarItemBase & {
35
- type: 'category';
36
- label: string;
37
- items: PropSidebarItem[];
38
- collapsed: boolean;
39
- collapsible: boolean;
45
+ export type PropTagDocList = {
46
+ allTagsPath: string;
47
+ name: string; // normalized name/label of the tag
48
+ permalink: string; // pathname of the tag
49
+ docs: PropTagDocListDoc[];
40
50
  };
41
51
 
42
- export type PropSidebarItem = PropSidebarItemLink | PropSidebarItemCategory;
43
-
44
- export type PropSidebars = {
45
- [sidebarId: string]: PropSidebarItem[];
52
+ export type PropTagsListPage = {
53
+ tags: {
54
+ name: string;
55
+ permalink: string;
56
+ count: number;
57
+ }[];
46
58
  };
47
-
48
- export type {GlobalDataVersion, GlobalDataDoc};
49
59
  }
50
60
 
51
61
  declare module '@theme/DocItem' {
@@ -64,8 +74,12 @@ declare module '@theme/DocItem' {
64
74
  readonly title: string;
65
75
  readonly image?: string;
66
76
  readonly keywords?: readonly string[];
77
+ /* eslint-disable camelcase */
67
78
  readonly hide_title?: boolean;
68
79
  readonly hide_table_of_contents?: boolean;
80
+ readonly toc_min_heading_level?: number;
81
+ readonly toc_max_heading_level?: number;
82
+ /* eslint-enable camelcase */
69
83
  };
70
84
 
71
85
  export type Metadata = {
@@ -79,9 +93,13 @@ declare module '@theme/DocItem' {
79
93
  readonly version?: string;
80
94
  readonly previous?: {readonly permalink: string; readonly title: string};
81
95
  readonly next?: {readonly permalink: string; readonly title: string};
96
+ readonly tags: readonly {
97
+ readonly label: string;
98
+ readonly permalink: string;
99
+ }[];
82
100
  };
83
101
 
84
- export type Props = {
102
+ export interface Props {
85
103
  readonly route: DocumentRoute;
86
104
  readonly versionMetadata: PropVersionMetadata;
87
105
  readonly content: {
@@ -91,18 +109,40 @@ declare module '@theme/DocItem' {
91
109
  readonly contentTitle: string | undefined;
92
110
  (): JSX.Element;
93
111
  };
94
- };
112
+ }
95
113
 
96
114
  const DocItem: (props: Props) => JSX.Element;
97
115
  export default DocItem;
98
116
  }
99
117
 
118
+ declare module '@theme/DocItemFooter' {
119
+ import type {Props} from '@theme/DocItem';
120
+
121
+ export default function DocItemFooter(props: Props): JSX.Element;
122
+ }
123
+
124
+ declare module '@theme/DocTagsListPage' {
125
+ import type {PropTagsListPage} from '@docusaurus/plugin-content-docs-types';
126
+
127
+ export interface Props extends PropTagsListPage {}
128
+ export default function DocTagsListPage(props: Props): JSX.Element;
129
+ }
130
+
131
+ declare module '@theme/DocTagDocListPage' {
132
+ import type {PropTagDocList} from '@docusaurus/plugin-content-docs-types';
133
+
134
+ export interface Props {
135
+ readonly tag: PropTagDocList;
136
+ }
137
+ export default function DocTagDocListPage(props: Props): JSX.Element;
138
+ }
139
+
100
140
  declare module '@theme/DocVersionBanner' {
101
141
  import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
102
142
 
103
- export type Props = {
143
+ export interface Props {
104
144
  readonly versionMetadata: PropVersionMetadata;
105
- };
145
+ }
106
146
 
107
147
  const DocVersionBanner: (props: Props) => JSX.Element;
108
148
  export default DocVersionBanner;
@@ -112,7 +152,7 @@ declare module '@theme/DocPage' {
112
152
  import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
113
153
  import type {DocumentRoute} from '@theme/DocItem';
114
154
 
115
- export type Props = {
155
+ export interface Props {
116
156
  readonly location: {readonly pathname: string};
117
157
  readonly versionMetadata: PropVersionMetadata;
118
158
  readonly route: {
@@ -120,20 +160,55 @@ declare module '@theme/DocPage' {
120
160
  readonly component: () => JSX.Element;
121
161
  readonly routes: DocumentRoute[];
122
162
  };
123
- };
163
+ }
124
164
 
125
165
  const DocPage: (props: Props) => JSX.Element;
126
166
  export default DocPage;
127
167
  }
128
168
 
129
169
  declare module '@theme/Seo' {
130
- export type Props = {
170
+ import type {ReactNode} from 'react';
171
+
172
+ export interface Props {
131
173
  readonly title?: string;
132
174
  readonly description?: string;
133
175
  readonly keywords?: readonly string[] | string;
134
176
  readonly image?: string;
135
- };
177
+ readonly children?: ReactNode;
178
+ }
136
179
 
137
180
  const Seo: (props: Props) => JSX.Element;
138
181
  export default Seo;
139
182
  }
183
+
184
+ declare module '@theme/hooks/useDocs' {
185
+ type GlobalPluginData = import('./types').GlobalPluginData;
186
+ type GlobalVersion = import('./types').GlobalVersion;
187
+ type ActivePlugin = import('./client/docsClientUtils').ActivePlugin;
188
+ type ActiveDocContext = import('./client/docsClientUtils').ActiveDocContext;
189
+ type DocVersionSuggestions =
190
+ import('./client/docsClientUtils').DocVersionSuggestions;
191
+ type GetActivePluginOptions =
192
+ import('./client/docsClientUtils').GetActivePluginOptions;
193
+
194
+ export type {GlobalPluginData, GlobalVersion};
195
+ export const useAllDocsData: () => Record<string, GlobalPluginData>;
196
+ export const useDocsData: (pluginId?: string) => GlobalPluginData;
197
+ export const useActivePlugin: (
198
+ options?: GetActivePluginOptions,
199
+ ) => ActivePlugin | undefined;
200
+ export const useActivePluginAndVersion: (
201
+ options?: GetActivePluginOptions,
202
+ ) =>
203
+ | {activePlugin: ActivePlugin; activeVersion: GlobalVersion | undefined}
204
+ | undefined;
205
+ export const useVersions: (pluginId?: string) => GlobalVersion[];
206
+ export const useLatestVersion: (pluginId?: string) => GlobalVersion;
207
+ export const useActiveVersion: (
208
+ pluginId?: string,
209
+ ) => GlobalVersion | undefined;
210
+ export const useActiveDocContext: (pluginId?: string) => ActiveDocContext;
211
+ export const useDocVersionSuggestions: (
212
+ pluginId?: string,
213
+ ) => DocVersionSuggestions;
214
+ }
package/src/props.ts CHANGED
@@ -5,18 +5,20 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {
9
- LoadedVersion,
8
+ import {LoadedVersion, VersionTag, DocMetadata} from './types';
9
+ import type {
10
10
  SidebarItemDoc,
11
11
  SidebarItemLink,
12
12
  SidebarItem,
13
- } from './types';
14
- import {
13
+ } from './sidebars/types';
14
+ import type {
15
15
  PropSidebars,
16
16
  PropVersionMetadata,
17
17
  PropSidebarItem,
18
+ PropTagDocList,
19
+ PropTagDocListDoc,
18
20
  } from '@docusaurus/plugin-content-docs-types';
19
- import {keyBy, mapValues} from 'lodash';
21
+ import {compact, keyBy, mapValues} from 'lodash';
20
22
 
21
23
  export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
22
24
  const docsById = keyBy(loadedVersion.docs, (doc) => doc.id);
@@ -43,6 +45,7 @@ Available document ids are:
43
45
  type: 'link',
44
46
  label: sidebarLabel || item.label || title,
45
47
  href: permalink,
48
+ className: item.className,
46
49
  customProps: item.customProps,
47
50
  };
48
51
  };
@@ -75,7 +78,40 @@ export function toVersionMetadataProp(
75
78
  version: loadedVersion.versionName,
76
79
  label: loadedVersion.versionLabel,
77
80
  banner: loadedVersion.versionBanner,
81
+ badge: loadedVersion.versionBadge,
82
+ className: loadedVersion.versionClassName,
78
83
  isLast: loadedVersion.isLast,
79
84
  docsSidebars: toSidebarsProp(loadedVersion),
80
85
  };
81
86
  }
87
+
88
+ export function toTagDocListProp({
89
+ allTagsPath,
90
+ tag,
91
+ docs,
92
+ }: {
93
+ allTagsPath: string;
94
+ tag: VersionTag;
95
+ docs: Pick<DocMetadata, 'id' | 'title' | 'description' | 'permalink'>[];
96
+ }): PropTagDocList {
97
+ function toDocListProp(): PropTagDocListDoc[] {
98
+ const list = compact(
99
+ tag.docIds.map((id) => docs.find((doc) => doc.id === id)),
100
+ );
101
+ // Sort docs by title
102
+ list.sort((doc1, doc2) => doc1.title.localeCompare(doc2.title));
103
+ return list.map((doc) => ({
104
+ id: doc.id,
105
+ title: doc.title,
106
+ description: doc.description,
107
+ permalink: doc.permalink,
108
+ }));
109
+ }
110
+
111
+ return {
112
+ name: tag.name,
113
+ permalink: tag.permalink,
114
+ docs: toDocListProp(),
115
+ allTagsPath,
116
+ };
117
+ }