@docusaurus/plugin-content-docs 2.0.0-beta.15d451942 → 2.0.0-beta.16

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 (214) hide show
  1. package/lib/categoryGeneratedIndex.d.ts +12 -0
  2. package/lib/categoryGeneratedIndex.js +39 -0
  3. package/lib/cli.d.ts +2 -2
  4. package/lib/cli.js +40 -52
  5. package/lib/client/docsClientUtils.d.ts +3 -25
  6. package/lib/client/docsClientUtils.js +27 -33
  7. package/lib/{theme/hooks/useDocs.d.ts → client/index.d.ts} +1 -2
  8. package/lib/client/index.js +75 -0
  9. package/lib/docFrontMatter.d.ts +1 -14
  10. package/lib/docFrontMatter.js +13 -6
  11. package/lib/docs.d.ts +40 -4
  12. package/lib/docs.js +170 -54
  13. package/lib/globalData.d.ts +5 -1
  14. package/lib/globalData.js +35 -2
  15. package/lib/index.d.ts +4 -3
  16. package/lib/index.js +124 -136
  17. package/lib/lastUpdate.js +16 -29
  18. package/lib/markdown/index.d.ts +3 -6
  19. package/lib/markdown/index.js +3 -3
  20. package/lib/markdown/linkify.d.ts +1 -1
  21. package/lib/markdown/linkify.js +3 -3
  22. package/lib/numberPrefix.d.ts +1 -1
  23. package/lib/numberPrefix.js +7 -6
  24. package/lib/options.d.ts +3 -3
  25. package/lib/options.js +52 -17
  26. package/lib/props.d.ts +7 -2
  27. package/lib/props.js +71 -14
  28. package/lib/routes.d.ts +28 -0
  29. package/lib/routes.js +110 -0
  30. package/lib/server-export.d.ts +8 -0
  31. package/lib/server-export.js +23 -0
  32. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +1 -6
  33. package/lib/sidebars/generator.js +190 -0
  34. package/lib/sidebars/index.d.ts +13 -0
  35. package/lib/sidebars/index.js +88 -0
  36. package/lib/sidebars/normalization.d.ts +13 -0
  37. package/lib/sidebars/normalization.js +55 -0
  38. package/lib/sidebars/postProcessor.d.ts +8 -0
  39. package/lib/sidebars/postProcessor.js +72 -0
  40. package/lib/sidebars/processor.d.ts +8 -0
  41. package/lib/sidebars/processor.js +79 -0
  42. package/lib/sidebars/types.d.ts +166 -0
  43. package/{src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars2.js → lib/sidebars/types.js} +2 -10
  44. package/lib/sidebars/utils.d.ts +43 -0
  45. package/lib/sidebars/utils.js +265 -0
  46. package/lib/sidebars/validation.d.ts +9 -0
  47. package/lib/sidebars/validation.js +137 -0
  48. package/lib/slug.d.ts +6 -4
  49. package/lib/slug.js +29 -18
  50. package/{src/__tests__/__fixtures__/site-with-doc-label/docusaurus.config.js → lib/tags.d.ts} +2 -8
  51. package/lib/tags.js +21 -0
  52. package/lib/translations.d.ts +2 -2
  53. package/lib/translations.js +87 -44
  54. package/lib/types.d.ts +55 -128
  55. package/lib/versions.d.ts +29 -4
  56. package/lib/versions.js +131 -89
  57. package/package.json +30 -26
  58. package/src/categoryGeneratedIndex.ts +59 -0
  59. package/src/cli.ts +48 -62
  60. package/src/client/docsClientUtils.ts +36 -71
  61. package/src/{theme/hooks/useDocs.ts → client/index.ts} +15 -10
  62. package/{types.d.ts → src/deps.d.ts} +0 -0
  63. package/src/docFrontMatter.ts +17 -22
  64. package/src/docs.ts +229 -45
  65. package/src/globalData.ts +53 -2
  66. package/src/index.ts +168 -177
  67. package/src/lastUpdate.ts +14 -33
  68. package/src/markdown/index.ts +9 -13
  69. package/src/markdown/linkify.ts +2 -2
  70. package/src/numberPrefix.ts +11 -8
  71. package/src/options.ts +59 -29
  72. package/src/plugin-content-docs.d.ts +256 -40
  73. package/src/props.ts +105 -21
  74. package/src/routes.ts +185 -0
  75. package/src/server-export.ts +24 -0
  76. package/src/sidebars/README.md +9 -0
  77. package/src/sidebars/generator.ts +263 -0
  78. package/src/sidebars/index.ts +113 -0
  79. package/src/sidebars/normalization.ts +85 -0
  80. package/src/sidebars/postProcessor.ts +94 -0
  81. package/src/sidebars/processor.ts +126 -0
  82. package/src/sidebars/types.ts +273 -0
  83. package/src/sidebars/utils.ts +392 -0
  84. package/src/sidebars/validation.ts +173 -0
  85. package/src/slug.ts +40 -22
  86. package/src/tags.ts +19 -0
  87. package/src/translations.ts +121 -62
  88. package/src/types.ts +62 -183
  89. package/src/versions.ts +202 -107
  90. package/lib/.tsbuildinfo +0 -4717
  91. package/lib/sidebarItemsGenerator.js +0 -211
  92. package/lib/sidebars.d.ts +0 -42
  93. package/lib/sidebars.js +0 -309
  94. package/lib/theme/hooks/useDocs.js +0 -72
  95. package/src/__tests__/__fixtures__/bad-id-site/docs/invalid-id.md +0 -5
  96. package/src/__tests__/__fixtures__/bad-slug-on-doc-home-site/docs/docWithSlug.md +0 -5
  97. package/src/__tests__/__fixtures__/empty-site/docusaurus.config.js +0 -16
  98. package/src/__tests__/__fixtures__/empty-site/sidebars.json +0 -1
  99. package/src/__tests__/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -34
  100. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -11
  101. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -11
  102. package/src/__tests__/__fixtures__/sidebars/sidebars-category.js +0 -44
  103. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -20
  104. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed.json +0 -21
  105. package/src/__tests__/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -10
  106. package/src/__tests__/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -20
  107. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -11
  108. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -11
  109. package/src/__tests__/__fixtures__/sidebars/sidebars-link.json +0 -11
  110. package/src/__tests__/__fixtures__/sidebars/sidebars-unknown-type.json +0 -14
  111. package/src/__tests__/__fixtures__/sidebars/sidebars-wrong-field.json +0 -20
  112. package/src/__tests__/__fixtures__/sidebars/sidebars.json +0 -20
  113. package/src/__tests__/__fixtures__/simple-site/docs/foo/bar.md +0 -69
  114. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +0 -67
  115. package/src/__tests__/__fixtures__/simple-site/docs/headingAsTitle.md +0 -1
  116. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +0 -52
  117. package/src/__tests__/__fixtures__/simple-site/docs/ipsum.md +0 -5
  118. package/src/__tests__/__fixtures__/simple-site/docs/lorem.md +0 -6
  119. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +0 -5
  120. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +0 -5
  121. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +0 -5
  122. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +0 -5
  123. package/src/__tests__/__fixtures__/simple-site/docs/slugs/absoluteSlug.md +0 -5
  124. package/src/__tests__/__fixtures__/simple-site/docs/slugs/relativeSlug.md +0 -5
  125. package/src/__tests__/__fixtures__/simple-site/docs/slugs/resolvedSlug.md +0 -5
  126. package/src/__tests__/__fixtures__/simple-site/docs/slugs/tryToEscapeSlug.md +0 -5
  127. package/src/__tests__/__fixtures__/simple-site/docusaurus.config.js +0 -14
  128. package/src/__tests__/__fixtures__/simple-site/sidebars.json +0 -23
  129. package/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json +0 -7
  130. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/0-getting-started.md +0 -3
  131. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/1-installation.md +0 -3
  132. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/00_api-overview.md +0 -3
  133. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/0 --- Client API.md +0 -1
  134. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/1 --- Server API.md +0 -1
  135. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/0. Plugin API.md +0 -1
  136. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/1. Theme API.md +0 -1
  137. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/_category_.yml +0 -1
  138. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/03_api-end.md +0 -3
  139. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/_category_.json +0 -3
  140. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/0-guide2.5.md +0 -8
  141. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/02-guide2.md +0 -7
  142. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/_category_.json +0 -3
  143. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/a-guide4.md +0 -7
  144. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/b-guide5.md +0 -7
  145. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/guide3.md +0 -8
  146. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/z-guide1.md +0 -8
  147. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docusaurus.config.js +0 -14
  148. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars.js +0 -23
  149. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +0 -7
  150. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-2.md +0 -8
  151. package/src/__tests__/__fixtures__/site-with-doc-label/sidebars.json +0 -14
  152. package/src/__tests__/__fixtures__/versioned-site/community/team.md +0 -1
  153. package/src/__tests__/__fixtures__/versioned-site/community_sidebars.json +0 -3
  154. package/src/__tests__/__fixtures__/versioned-site/community_versioned_docs/version-1.0.0/team.md +0 -1
  155. package/src/__tests__/__fixtures__/versioned-site/community_versioned_sidebars/version-1.0.0-sidebars.json +0 -3
  156. package/src/__tests__/__fixtures__/versioned-site/community_versions.json +0 -1
  157. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +0 -4
  158. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +0 -1
  159. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/absoluteSlug.md +0 -5
  160. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/relativeSlug.md +0 -5
  161. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/resolvedSlug.md +0 -5
  162. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/tryToEscapeSlug.md +0 -5
  163. package/src/__tests__/__fixtures__/versioned-site/docusaurus.config.js +0 -18
  164. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  165. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md +0 -5
  166. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  167. package/src/__tests__/__fixtures__/versioned-site/sidebars.json +0 -10
  168. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/bar.md +0 -4
  169. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/baz.md +0 -1
  170. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +0 -1
  171. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/foo/bar.md +0 -1
  172. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +0 -1
  173. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md +0 -5
  174. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootRelativeSlug.md +0 -5
  175. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootResolvedSlug.md +0 -5
  176. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md +0 -5
  177. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md +0 -5
  178. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/relativeSlug.md +0 -5
  179. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md +0 -5
  180. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md +0 -5
  181. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
  182. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +0 -10
  183. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-withSlugs-sidebars.json +0 -5
  184. package/src/__tests__/__fixtures__/versioned-site/versions.json +0 -5
  185. package/src/__tests__/__snapshots__/cli.test.ts.snap +0 -90
  186. package/src/__tests__/__snapshots__/index.test.ts.snap +0 -1907
  187. package/src/__tests__/__snapshots__/sidebars.test.ts.snap +0 -218
  188. package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -487
  189. package/src/__tests__/cli.test.ts +0 -333
  190. package/src/__tests__/docFrontMatter.test.ts +0 -204
  191. package/src/__tests__/docs.test.ts +0 -875
  192. package/src/__tests__/index.test.ts +0 -1831
  193. package/src/__tests__/lastUpdate.test.ts +0 -68
  194. package/src/__tests__/numberPrefix.test.ts +0 -199
  195. package/src/__tests__/options.test.ts +0 -232
  196. package/src/__tests__/sidebarItemsGenerator.test.ts +0 -336
  197. package/src/__tests__/sidebars.test.ts +0 -638
  198. package/src/__tests__/slug.test.ts +0 -109
  199. package/src/__tests__/translations.test.ts +0 -159
  200. package/src/__tests__/versions.test.ts +0 -718
  201. package/src/client/__tests__/docsClientUtils.test.ts +0 -372
  202. package/src/markdown/__tests__/__fixtures__/docs/doc-localized.md +0 -1
  203. package/src/markdown/__tests__/__fixtures__/docs/doc1.md +0 -13
  204. package/src/markdown/__tests__/__fixtures__/docs/doc2.md +0 -12
  205. package/src/markdown/__tests__/__fixtures__/docs/doc4.md +0 -19
  206. package/src/markdown/__tests__/__fixtures__/docs/doc5.md +0 -6
  207. package/src/markdown/__tests__/__fixtures__/docs/subdir/doc3.md +0 -3
  208. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/doc2.md +0 -7
  209. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/subdir/doc1.md +0 -3
  210. package/src/markdown/__tests__/__snapshots__/linkify.test.ts.snap +0 -82
  211. package/src/markdown/__tests__/linkify.test.ts +0 -190
  212. package/src/sidebarItemsGenerator.ts +0 -307
  213. package/src/sidebars.ts +0 -489
  214. package/tsconfig.json +0 -9
package/src/index.ts CHANGED
@@ -7,10 +7,6 @@
7
7
 
8
8
  import path from 'path';
9
9
 
10
- import {
11
- STATIC_DIR_NAME,
12
- DEFAULT_PLUGIN_ID,
13
- } from '@docusaurus/core/lib/constants';
14
10
  import {
15
11
  normalizeUrl,
16
12
  docuHash,
@@ -18,47 +14,60 @@ import {
18
14
  reportMessage,
19
15
  posixPath,
20
16
  addTrailingPathSeparator,
17
+ createAbsoluteFilePathMatcher,
18
+ createSlugger,
19
+ DEFAULT_PLUGIN_ID,
21
20
  } from '@docusaurus/utils';
22
- import {LoadContext, Plugin, RouteConfig} from '@docusaurus/types';
23
- import {loadSidebars, createSidebarsUtils, processSidebars} from './sidebars';
24
- import {readVersionDocs, processDocMetadata} from './docs';
21
+ import type {LoadContext, Plugin} from '@docusaurus/types';
22
+ import {loadSidebars} from './sidebars';
23
+ import {CategoryMetadataFilenamePattern} from './sidebars/generator';
24
+ import {
25
+ readVersionDocs,
26
+ processDocMetadata,
27
+ addDocNavigation,
28
+ getMainDocId,
29
+ } from './docs';
25
30
  import {getDocsDirPaths, readVersionsMetadata} from './versions';
26
31
 
27
- import {
28
- PluginOptions,
32
+ import type {
29
33
  LoadedContent,
30
34
  SourceToPermalink,
31
35
  DocMetadataBase,
32
- DocMetadata,
33
- GlobalPluginData,
34
36
  VersionMetadata,
35
- DocNavLink,
36
37
  LoadedVersion,
37
38
  DocFile,
38
39
  DocsMarkdownOption,
40
+ VersionTag,
41
+ DocFrontMatter,
39
42
  } from './types';
40
- import {PermalinkToSidebar} from '@docusaurus/plugin-content-docs-types';
41
- import {RuleSetRule} from 'webpack';
43
+ import type {RuleSetRule} from 'webpack';
42
44
  import {cliDocsVersionCommand} from './cli';
43
45
  import {VERSIONS_JSON_FILE} from './constants';
44
- import {flatten, keyBy, compact} from 'lodash';
45
46
  import {toGlobalDataVersion} from './globalData';
46
- import {toVersionMetadataProp} from './props';
47
+ import {toTagDocListProp} from './props';
47
48
  import {
48
49
  translateLoadedContent,
49
50
  getLoadedContentTranslationFiles,
50
51
  } from './translations';
51
- import {CategoryMetadataFilenamePattern} from './sidebarItemsGenerator';
52
+ import logger from '@docusaurus/logger';
53
+ import {getVersionTags} from './tags';
54
+ import {createVersionRoutes} from './routes';
55
+ import type {
56
+ PropTagsListPage,
57
+ PluginOptions,
58
+ } from '@docusaurus/plugin-content-docs';
59
+ import type {GlobalPluginData} from '@docusaurus/plugin-content-docs/client';
60
+ import {createSidebarsUtils} from './sidebars/utils';
61
+ import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
52
62
 
53
- export default function pluginContentDocs(
63
+ export default async function pluginContentDocs(
54
64
  context: LoadContext,
55
65
  options: PluginOptions,
56
- ): Plugin<LoadedContent> {
66
+ ): Promise<Plugin<LoadedContent>> {
57
67
  const {siteDir, generatedFilesDir, baseUrl, siteConfig} = context;
58
68
 
59
- const versionsMetadata = readVersionsMetadata({context, options});
69
+ const versionsMetadata = await readVersionsMetadata({context, options});
60
70
 
61
- const sourceToPermalink: SourceToPermalink = {};
62
71
  const pluginId = options.id ?? DEFAULT_PLUGIN_ID;
63
72
 
64
73
  const pluginDataDirRoot = path.join(
@@ -72,14 +81,6 @@ export default function pluginContentDocs(
72
81
  return {
73
82
  name: 'docusaurus-plugin-content-docs',
74
83
 
75
- getThemePath() {
76
- return path.resolve(__dirname, './theme');
77
- },
78
-
79
- getTypeScriptThemePath() {
80
- return path.resolve(__dirname, '..', 'src', 'theme');
81
- },
82
-
83
84
  extendCli(cli) {
84
85
  const isDefaultPluginId = pluginId === DEFAULT_PLUGIN_ID;
85
86
 
@@ -100,6 +101,8 @@ export default function pluginContentDocs(
100
101
  cliDocsVersionCommand(version, siteDir, pluginId, {
101
102
  path: options.path,
102
103
  sidebarPath: options.sidebarPath,
104
+ sidebarCollapsed: options.sidebarCollapsed,
105
+ sidebarCollapsible: options.sidebarCollapsible,
103
106
  });
104
107
  });
105
108
  },
@@ -108,22 +111,12 @@ export default function pluginContentDocs(
108
111
  return getLoadedContentTranslationFiles(content);
109
112
  },
110
113
 
111
- getClientModules() {
112
- const modules = [];
113
- if (options.admonitions) {
114
- modules.push(require.resolve('remark-admonitions/styles/infima.css'));
115
- }
116
- return modules;
117
- },
118
-
119
114
  getPathsToWatch() {
120
115
  function getVersionPathsToWatch(version: VersionMetadata): string[] {
121
116
  const result = [
122
- ...flatten(
123
- options.include.map((pattern) =>
124
- getDocsDirPaths(version).map(
125
- (docsDirPath) => `${docsDirPath}/${pattern}`,
126
- ),
117
+ ...options.include.flatMap((pattern) =>
118
+ getDocsDirPaths(version).map(
119
+ (docsDirPath) => `${docsDirPath}/${pattern}`,
127
120
  ),
128
121
  ),
129
122
  `${version.contentPath}/**/${CategoryMetadataFilenamePattern}`,
@@ -134,7 +127,7 @@ export default function pluginContentDocs(
134
127
  return result;
135
128
  }
136
129
 
137
- return flatten(versionsMetadata.map(getVersionPathsToWatch));
130
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
138
131
  },
139
132
 
140
133
  async loadContent() {
@@ -144,12 +137,12 @@ export default function pluginContentDocs(
144
137
  const docFiles = await readVersionDocs(versionMetadata, options);
145
138
  if (docFiles.length === 0) {
146
139
  throw new Error(
147
- `Docs version ${
140
+ `Docs version "${
148
141
  versionMetadata.versionName
149
- } has no docs! At least one doc should exist at path=[${path.relative(
142
+ }" has no docs! At least one doc should exist at "${path.relative(
150
143
  siteDir,
151
144
  versionMetadata.contentPath,
152
- )}]`,
145
+ )}".`,
153
146
  );
154
147
  }
155
148
  async function processVersionDoc(docFile: DocFile) {
@@ -163,101 +156,52 @@ export default function pluginContentDocs(
163
156
  return Promise.all(docFiles.map(processVersionDoc));
164
157
  }
165
158
 
166
- async function loadVersion(
159
+ async function doLoadVersion(
167
160
  versionMetadata: VersionMetadata,
168
161
  ): Promise<LoadedVersion> {
169
- const unprocessedSidebars = loadSidebars(
170
- versionMetadata.sidebarFilePath,
171
- );
172
-
173
- const docsBase: DocMetadataBase[] = await loadVersionDocsBase(
162
+ const docs: DocMetadataBase[] = await loadVersionDocsBase(
174
163
  versionMetadata,
175
164
  );
176
- const docsBaseById: Record<string, DocMetadataBase> = keyBy(
177
- docsBase,
178
- (doc) => doc.id,
179
- );
180
165
 
181
- const sidebars = await processSidebars({
166
+ const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
182
167
  sidebarItemsGenerator: options.sidebarItemsGenerator,
183
168
  numberPrefixParser: options.numberPrefixParser,
184
- unprocessedSidebars,
185
- docs: docsBase,
169
+ docs,
186
170
  version: versionMetadata,
171
+ sidebarOptions: {
172
+ sidebarCollapsed: options.sidebarCollapsed,
173
+ sidebarCollapsible: options.sidebarCollapsible,
174
+ },
175
+ categoryLabelSlugger: createSlugger(),
187
176
  });
188
177
 
189
178
  const sidebarsUtils = createSidebarsUtils(sidebars);
190
179
 
191
- const validDocIds = Object.keys(docsBaseById);
192
- sidebarsUtils.checkSidebarsDocIds(validDocIds);
193
-
194
- // Add sidebar/next/previous to the docs
195
- function addNavData(doc: DocMetadataBase): DocMetadata {
196
- const {
197
- sidebarName,
198
- previousId,
199
- nextId,
200
- } = sidebarsUtils.getDocNavigation(doc.id);
201
- const toDocNavLink = (navDocId: string): DocNavLink => ({
202
- title: docsBaseById[navDocId].title,
203
- permalink: docsBaseById[navDocId].permalink,
204
- });
205
- return {
206
- ...doc,
207
- sidebar: sidebarName,
208
- previous: previousId ? toDocNavLink(previousId) : undefined,
209
- next: nextId ? toDocNavLink(nextId) : undefined,
210
- };
211
- }
212
-
213
- const docs = docsBase.map(addNavData);
214
-
215
- // sort to ensure consistent output for tests
216
- docs.sort((a, b) => a.id.localeCompare(b.id));
217
-
218
- // TODO annoying side effect!
219
- Object.values(docs).forEach((loadedDoc) => {
220
- const {source, permalink} = loadedDoc;
221
- sourceToPermalink[source] = permalink;
222
- });
223
-
224
- // TODO really useful? replace with global state logic?
225
- const permalinkToSidebar: PermalinkToSidebar = {};
226
- Object.values(docs).forEach((doc) => {
227
- if (doc.sidebar) {
228
- permalinkToSidebar[doc.permalink] = doc.sidebar;
229
- }
230
- });
231
-
232
- // The "main doc" is the "version entry point"
233
- // We browse this doc by clicking on a version:
234
- // - the "home" doc (at '/docs/')
235
- // - the first doc of the first sidebar
236
- // - a random doc (if no docs are in any sidebar... edge case)
237
- function getMainDoc(): DocMetadata {
238
- const versionHomeDoc = docs.find(
239
- (doc) =>
240
- doc.unversionedId === options.homePageId || doc.slug === '/',
241
- );
242
- const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
243
- if (versionHomeDoc) {
244
- return versionHomeDoc;
245
- } else if (firstDocIdOfFirstSidebar) {
246
- return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar)!;
247
- } else {
248
- return docs[0];
249
- }
250
- }
251
-
252
180
  return {
253
181
  ...versionMetadata,
254
- mainDocId: getMainDoc().unversionedId,
182
+ docs: addDocNavigation(
183
+ docs,
184
+ sidebarsUtils,
185
+ versionMetadata.sidebarFilePath as string,
186
+ ),
255
187
  sidebars,
256
- permalinkToSidebar,
257
- docs: docs.map(addNavData),
188
+ mainDocId: getMainDocId({docs, sidebarsUtils}),
189
+ categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
190
+ docs,
191
+ sidebarsUtils,
192
+ }),
258
193
  };
259
194
  }
260
195
 
196
+ async function loadVersion(versionMetadata: VersionMetadata) {
197
+ try {
198
+ return await doLoadVersion(versionMetadata);
199
+ } catch (err) {
200
+ logger.error`Loading of version failed for version name=${versionMetadata.versionName}`;
201
+ throw err;
202
+ }
203
+ }
204
+
261
205
  return {
262
206
  loadedVersions: await Promise.all(versionsMetadata.map(loadVersion)),
263
207
  };
@@ -269,71 +213,94 @@ export default function pluginContentDocs(
269
213
 
270
214
  async contentLoaded({content, actions}) {
271
215
  const {loadedVersions} = content;
272
- const {docLayoutComponent, docItemComponent} = options;
216
+ const {
217
+ docLayoutComponent,
218
+ docItemComponent,
219
+ docCategoryGeneratedIndexComponent,
220
+ breadcrumbs,
221
+ } = options;
273
222
  const {addRoute, createData, setGlobalData} = actions;
274
223
 
275
- const createDocRoutes = async (
276
- docs: DocMetadata[],
277
- ): Promise<RouteConfig[]> => {
278
- const routes = await Promise.all(
279
- docs.map(async (metadataItem) => {
280
- await createData(
281
- // Note that this created data path must be in sync with
282
- // metadataPath provided to mdx-loader.
283
- `${docuHash(metadataItem.source)}.json`,
284
- JSON.stringify(metadataItem, null, 2),
224
+ async function createVersionTagsRoutes(version: LoadedVersion) {
225
+ const versionTags = getVersionTags(version.docs);
226
+
227
+ // TODO tags should be a sub route of the version route
228
+ async function createTagsListPage() {
229
+ const tagsProp: PropTagsListPage['tags'] = Object.values(
230
+ versionTags,
231
+ ).map((tagValue) => ({
232
+ name: tagValue.name,
233
+ permalink: tagValue.permalink,
234
+ count: tagValue.docIds.length,
235
+ }));
236
+
237
+ // Only create /tags page if there are tags.
238
+ if (Object.keys(tagsProp).length > 0) {
239
+ const tagsPropPath = await createData(
240
+ `${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
241
+ JSON.stringify(tagsProp, null, 2),
285
242
  );
286
-
287
- return {
288
- path: metadataItem.permalink,
289
- component: docItemComponent,
243
+ addRoute({
244
+ path: version.tagsPath,
290
245
  exact: true,
246
+ component: options.docTagsListComponent,
291
247
  modules: {
292
- content: metadataItem.source,
248
+ tags: aliasedSource(tagsPropPath),
293
249
  },
294
- };
295
- }),
296
- );
297
-
298
- return routes.sort((a, b) => a.path.localeCompare(b.path));
299
- };
250
+ });
251
+ }
252
+ }
300
253
 
301
- async function handleVersion(loadedVersion: LoadedVersion) {
302
- const versionMetadataPropPath = await createData(
303
- `${docuHash(
304
- `version-${loadedVersion.versionName}-metadata-prop`,
305
- )}.json`,
306
- JSON.stringify(
307
- toVersionMetadataProp(pluginId, loadedVersion),
308
- null,
309
- 2,
310
- ),
311
- );
254
+ // TODO tags should be a sub route of the version route
255
+ async function createTagDocListPage(tag: VersionTag) {
256
+ const tagProps = toTagDocListProp({
257
+ allTagsPath: version.tagsPath,
258
+ tag,
259
+ docs: version.docs,
260
+ });
261
+ const tagPropPath = await createData(
262
+ `${docuHash(`tag-${tag.permalink}`)}.json`,
263
+ JSON.stringify(tagProps, null, 2),
264
+ );
265
+ addRoute({
266
+ path: tag.permalink,
267
+ component: options.docTagDocListComponent,
268
+ exact: true,
269
+ modules: {
270
+ tag: aliasedSource(tagPropPath),
271
+ },
272
+ });
273
+ }
312
274
 
313
- addRoute({
314
- path: loadedVersion.versionPath,
315
- // allow matching /docs/* as well
316
- exact: false,
317
- // main docs component (DocPage)
318
- component: docLayoutComponent,
319
- // sub-routes for each doc
320
- routes: await createDocRoutes(loadedVersion.docs),
321
- modules: {
322
- versionMetadata: aliasedSource(versionMetadataPropPath),
323
- },
324
- priority: loadedVersion.routePriority,
325
- });
275
+ await createTagsListPage();
276
+ await Promise.all(Object.values(versionTags).map(createTagDocListPage));
326
277
  }
327
278
 
328
- await Promise.all(loadedVersions.map(handleVersion));
279
+ await Promise.all(
280
+ loadedVersions.map((loadedVersion) =>
281
+ createVersionRoutes({
282
+ loadedVersion,
283
+ docItemComponent,
284
+ docLayoutComponent,
285
+ docCategoryGeneratedIndexComponent,
286
+ pluginId,
287
+ aliasedSource,
288
+ actions,
289
+ }),
290
+ ),
291
+ );
292
+
293
+ // TODO tags should be a sub route of the version route
294
+ await Promise.all(loadedVersions.map(createVersionTagsRoutes));
329
295
 
330
296
  setGlobalData<GlobalPluginData>({
331
297
  path: normalizeUrl([baseUrl, options.routeBasePath]),
332
298
  versions: loadedVersions.map(toGlobalDataVersion),
299
+ breadcrumbs,
333
300
  });
334
301
  },
335
302
 
336
- configureWebpack(_config, isServer, utils) {
303
+ configureWebpack(_config, isServer, utils, content) {
337
304
  const {getJSLoader} = utils;
338
305
  const {
339
306
  rehypePlugins,
@@ -342,9 +309,16 @@ export default function pluginContentDocs(
342
309
  beforeDefaultRemarkPlugins,
343
310
  } = options;
344
311
 
312
+ function getSourceToPermalink(): SourceToPermalink {
313
+ const allDocs = content.loadedVersions.flatMap((v) => v.docs);
314
+ return Object.fromEntries(
315
+ allDocs.map(({source, permalink}) => [source, permalink]),
316
+ );
317
+ }
318
+
345
319
  const docsMarkdownOptions: DocsMarkdownOption = {
346
320
  siteDir,
347
- sourceToPermalink,
321
+ sourceToPermalink: getSourceToPermalink(),
348
322
  versionsMetadata,
349
323
  onBrokenMarkdownLink: (brokenMarkdownLink) => {
350
324
  if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
@@ -358,12 +332,13 @@ export default function pluginContentDocs(
358
332
  };
359
333
 
360
334
  function createMDXLoaderRule(): RuleSetRule {
335
+ const contentDirs = versionsMetadata.flatMap(getDocsDirPaths);
361
336
  return {
362
- test: /(\.mdx?)$/,
363
- include: flatten(versionsMetadata.map(getDocsDirPaths))
337
+ test: /\.mdx?$/i,
338
+ include: contentDirs
364
339
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
365
340
  .map(addTrailingPathSeparator),
366
- use: compact([
341
+ use: [
367
342
  getJSLoader({isServer}),
368
343
  {
369
344
  loader: require.resolve('@docusaurus/mdx-loader'),
@@ -372,20 +347,36 @@ export default function pluginContentDocs(
372
347
  rehypePlugins,
373
348
  beforeDefaultRehypePlugins,
374
349
  beforeDefaultRemarkPlugins,
375
- staticDir: path.join(siteDir, STATIC_DIR_NAME),
350
+ staticDirs: siteConfig.staticDirectories.map((dir) =>
351
+ path.resolve(siteDir, dir),
352
+ ),
353
+ siteDir,
354
+ isMDXPartial: createAbsoluteFilePathMatcher(
355
+ options.exclude,
356
+ contentDirs,
357
+ ),
376
358
  metadataPath: (mdxPath: string) => {
377
359
  // Note that metadataPath must be the same/in-sync as
378
360
  // the path from createData for each MDX.
379
361
  const aliasedPath = aliasedSitePath(mdxPath, siteDir);
380
362
  return path.join(dataDir, `${docuHash(aliasedPath)}.json`);
381
363
  },
364
+ // Assets allow to convert some relative images paths to
365
+ // require(...) calls
366
+ createAssets: ({
367
+ frontMatter,
368
+ }: {
369
+ frontMatter: DocFrontMatter;
370
+ }) => ({
371
+ image: frontMatter.image,
372
+ }),
382
373
  },
383
374
  },
384
375
  {
385
376
  loader: path.resolve(__dirname, './markdown/index.js'),
386
377
  options: docsMarkdownOptions,
387
378
  },
388
- ]),
379
+ ].filter(Boolean),
389
380
  };
390
381
  }
391
382
 
package/src/lastUpdate.ts CHANGED
@@ -5,13 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import shell from 'shelljs';
9
- import execa from 'execa';
8
+ import logger from '@docusaurus/logger';
9
+ import {getFileCommitDate, GitNotFoundError} from '@docusaurus/utils';
10
10
 
11
11
  type FileLastUpdateData = {timestamp?: number; author?: string};
12
12
 
13
- const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+), (.+)$/;
14
-
15
13
  let showedGitRequirementError = false;
16
14
 
17
15
  export async function getFileLastUpdate(
@@ -20,39 +18,22 @@ export async function getFileLastUpdate(
20
18
  if (!filePath) {
21
19
  return null;
22
20
  }
23
- function getTimestampAndAuthor(str: string): FileLastUpdateData | null {
24
- if (!str) {
25
- return null;
26
- }
27
-
28
- const temp = str.match(GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX);
29
- return !temp || temp.length < 3
30
- ? null
31
- : {timestamp: +temp[1], author: temp[2]};
32
- }
33
21
 
34
22
  // Wrap in try/catch in case the shell commands fail
35
23
  // (e.g. project doesn't use Git, etc).
36
24
  try {
37
- if (!shell.which('git')) {
38
- if (!showedGitRequirementError) {
39
- showedGitRequirementError = true;
40
- console.warn('Sorry, the docs plugin last update options require Git.');
41
- }
42
-
43
- return null;
25
+ const result = getFileCommitDate(filePath, {
26
+ age: 'newest',
27
+ includeAuthor: true,
28
+ });
29
+ return {timestamp: result.timestamp, author: result.author};
30
+ } catch (err) {
31
+ if (err instanceof GitNotFoundError && !showedGitRequirementError) {
32
+ logger.warn('Sorry, the docs plugin last update options require Git.');
33
+ showedGitRequirementError = true;
34
+ } else {
35
+ logger.error(err);
44
36
  }
45
-
46
- const {stdout} = await execa('git', [
47
- 'log',
48
- '-1',
49
- '--format=%ct, %an',
50
- filePath,
51
- ]);
52
- return getTimestampAndAuthor(stdout);
53
- } catch (error) {
54
- console.error(error);
37
+ return null;
55
38
  }
56
-
57
- return null;
58
39
  }
@@ -6,21 +6,17 @@
6
6
  */
7
7
 
8
8
  import {linkify} from './linkify';
9
- import {DocsMarkdownOption} from '../types';
9
+ import type {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
+ }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {DocsMarkdownOption} from '../types';
8
+ import type {DocsMarkdownOption} from '../types';
9
9
  import {getDocsDirPaths} from '../versions';
10
10
  import {replaceMarkdownLinks} from '@docusaurus/utils';
11
11
 
@@ -17,7 +17,7 @@ function getVersion(filePath: string, options: DocsMarkdownOption) {
17
17
  );
18
18
  if (!versionFound) {
19
19
  throw new Error(
20
- `Unexpected, markdown file does not belong to any docs version! file=${filePath}`,
20
+ `Unexpected error: Markdown file at "${filePath}" does not belong to any docs version!`,
21
21
  );
22
22
  }
23
23
  return versionFound;
@@ -5,25 +5,28 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {NumberPrefixParser} from './types';
8
+ import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs';
9
9
 
10
10
  // Best-effort to avoid parsing some patterns as number prefix
11
- const IgnoredPrefixPatterns = (function () {
11
+ const IgnoredPrefixPatterns = (() => {
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
- // note: we could try to parse float numbers in filenames but that is probably not worth it
17
- // as a version such as "8.0" can be interpreted as both a version and a float
18
- // User can configure his own NumberPrefixParser if he wants 8.0 to be interpreted as a float
19
- const VersionLikePrefixRegex = /^(\d+[-_.]\d+)(.*)$/;
17
+ // note: we could try to parse float numbers in filenames but that is
18
+ // probably not worth it as a version such as "8.0" can be interpreted as both
19
+ // a version and a float. User can configure her own NumberPrefixParser if
20
+ // she wants 8.0 to be interpreted as a float
21
+ const VersionLikePrefixRegex = /^\d+[-_.]\d+.*$/;
20
22
 
21
23
  return new RegExp(
22
24
  `${DateLikePrefixRegex.source}|${VersionLikePrefixRegex.source}`,
23
25
  );
24
26
  })();
25
27
 
26
- const NumberPrefixRegex = /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
28
+ const NumberPrefixRegex =
29
+ /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
27
30
 
28
31
  // 0-myDoc => {filename: myDoc, numberPrefix: 0}
29
32
  // 003 - myDoc => {filename: myDoc, numberPrefix: 3}