@docusaurus/plugin-content-docs 2.0.0-beta.1ec2c95e3 → 2.0.0-beta.21

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