@docusaurus/plugin-content-docs 2.0.0-beta.1decd6f80 → 2.0.0-beta.20

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