@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/docs.ts CHANGED
@@ -7,32 +7,40 @@
7
7
 
8
8
  import path from 'path';
9
9
  import fs from 'fs-extra';
10
+ import logger from '@docusaurus/logger';
10
11
  import {
11
12
  aliasedSitePath,
12
13
  getEditUrl,
13
14
  getFolderContainingFile,
15
+ getContentPathList,
14
16
  normalizeUrl,
15
17
  parseMarkdownString,
16
18
  posixPath,
19
+ Globby,
20
+ normalizeFrontMatterTags,
17
21
  } from '@docusaurus/utils';
18
- import {LoadContext} from '@docusaurus/types';
19
22
 
20
23
  import {getFileLastUpdate} from './lastUpdate';
21
- import {
22
- DocFile,
23
- DocMetadataBase,
24
- LastUpdateData,
25
- MetadataOptions,
26
- PluginOptions,
27
- VersionMetadata,
28
- } from './types';
29
24
  import getSlug from './slug';
30
25
  import {CURRENT_VERSION_NAME} from './constants';
31
- import globby from 'globby';
32
- import {getDocsDirPaths} from './versions';
33
26
  import {stripPathNumberPrefixes} from './numberPrefix';
34
- import {validateDocFrontMatter} from './docFrontMatter';
35
- import chalk from 'chalk';
27
+ import {validateDocFrontMatter} from './frontMatter';
28
+ import {toDocNavigationLink, toNavigationLink} from './sidebars/utils';
29
+ import type {
30
+ MetadataOptions,
31
+ PluginOptions,
32
+ CategoryIndexMatcher,
33
+ DocMetadataBase,
34
+ DocMetadata,
35
+ PropNavigationLink,
36
+ LastUpdateData,
37
+ VersionMetadata,
38
+ DocFrontMatter,
39
+ LoadedVersion,
40
+ } from '@docusaurus/plugin-content-docs';
41
+ import type {LoadContext} from '@docusaurus/types';
42
+ import type {SidebarsUtils} from './sidebars/utils';
43
+ import type {DocFile} from './types';
36
44
 
37
45
  type LastUpdateOptions = Pick<
38
46
  PluginOptions,
@@ -75,7 +83,7 @@ export async function readDocFile(
75
83
  options: LastUpdateOptions,
76
84
  ): Promise<DocFile> {
77
85
  const contentPath = await getFolderContainingFile(
78
- getDocsDirPaths(versionMetadata),
86
+ getContentPathList(versionMetadata),
79
87
  source,
80
88
  );
81
89
 
@@ -92,30 +100,45 @@ export async function readVersionDocs(
92
100
  versionMetadata: VersionMetadata,
93
101
  options: Pick<
94
102
  PluginOptions,
95
- 'include' | 'showLastUpdateAuthor' | 'showLastUpdateTime'
103
+ 'include' | 'exclude' | 'showLastUpdateAuthor' | 'showLastUpdateTime'
96
104
  >,
97
105
  ): Promise<DocFile[]> {
98
- const sources = await globby(options.include, {
106
+ const sources = await Globby(options.include, {
99
107
  cwd: versionMetadata.contentPath,
108
+ ignore: options.exclude,
100
109
  });
101
110
  return Promise.all(
102
111
  sources.map((source) => readDocFile(versionMetadata, source, options)),
103
112
  );
104
113
  }
105
114
 
115
+ export type DocEnv = 'production' | 'development';
116
+
117
+ /** Docs with draft front matter are only considered draft in production. */
118
+ function isDraftForEnvironment({
119
+ env,
120
+ frontMatter,
121
+ }: {
122
+ frontMatter: DocFrontMatter;
123
+ env: DocEnv;
124
+ }): boolean {
125
+ return (env === 'production' && frontMatter.draft) ?? false;
126
+ }
127
+
106
128
  function doProcessDocMetadata({
107
129
  docFile,
108
130
  versionMetadata,
109
131
  context,
110
132
  options,
133
+ env,
111
134
  }: {
112
135
  docFile: DocFile;
113
136
  versionMetadata: VersionMetadata;
114
137
  context: LoadContext;
115
138
  options: MetadataOptions;
139
+ env: DocEnv;
116
140
  }): DocMetadataBase {
117
141
  const {source, content, lastUpdate, contentPath, filePath} = docFile;
118
- const {homePageId} = options;
119
142
  const {siteDir, i18n} = context;
120
143
 
121
144
  const {
@@ -128,25 +151,22 @@ function doProcessDocMetadata({
128
151
  const {
129
152
  custom_edit_url: customEditURL,
130
153
 
131
- // Strip number prefixes by default (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc) by default,
132
- // but allow to disable this behavior with frontmatterr
133
- // eslint-disable-next-line camelcase
134
- parse_number_prefixes = true,
154
+ // Strip number prefixes by default
155
+ // (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
156
+ // but allow to disable this behavior with front matter
157
+ parse_number_prefixes: parseNumberPrefixes = true,
135
158
  } = frontMatter;
136
159
 
137
- // ex: api/plugins/myDoc -> myDoc
138
- // ex: myDoc -> myDoc
160
+ // E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
139
161
  const sourceFileNameWithoutExtension = path.basename(
140
162
  source,
141
163
  path.extname(source),
142
164
  );
143
165
 
144
- // ex: api/plugins/myDoc -> api/plugins
145
- // ex: myDoc -> .
166
+ // E.g. api/plugins/myDoc -> api/plugins; myDoc -> .
146
167
  const sourceDirName = path.dirname(source);
147
168
 
148
- // eslint-disable-next-line camelcase
149
- const {filename: unprefixedFileName, numberPrefix} = parse_number_prefixes
169
+ const {filename: unprefixedFileName, numberPrefix} = parseNumberPrefixes
150
170
  ? options.numberPrefixParser(sourceFileNameWithoutExtension)
151
171
  : {filename: sourceFileNameWithoutExtension, numberPrefix: undefined};
152
172
 
@@ -155,7 +175,8 @@ function doProcessDocMetadata({
155
175
  throw new Error(`Document id "${baseID}" cannot include slash.`);
156
176
  }
157
177
 
158
- // For autogenerated sidebars, sidebar position can come from filename number prefix or frontmatter
178
+ // For autogenerated sidebars, sidebar position can come from filename number
179
+ // prefix or front matter
159
180
  const sidebarPosition: number | undefined =
160
181
  frontMatter.sidebar_position ?? numberPrefix;
161
182
 
@@ -168,14 +189,13 @@ function doProcessDocMetadata({
168
189
  : `version-${versionMetadata.versionName}`;
169
190
 
170
191
  // TODO legacy retrocompatibility
171
- // I think it's bad to affect the frontmatter id with the dirname?
192
+ // I think it's bad to affect the front matter id with the dirname?
172
193
  function computeDirNameIdPrefix() {
173
194
  if (sourceDirName === '.') {
174
195
  return undefined;
175
196
  }
176
197
  // Eventually remove the number prefixes from intermediate directories
177
- // eslint-disable-next-line camelcase
178
- return parse_number_prefixes
198
+ return parseNumberPrefixes
179
199
  ? stripPathNumberPrefixes(sourceDirName, options.numberPrefixParser)
180
200
  : sourceDirName;
181
201
  }
@@ -188,31 +208,23 @@ function doProcessDocMetadata({
188
208
  // legacy versioned id, requires a breaking change to modify this
189
209
  const id = [versionIdPrefix, unversionedId].filter(Boolean).join('/');
190
210
 
191
- // TODO remove soon, deprecated homePageId
192
- const isDocsHomePage = unversionedId === (homePageId ?? '_index');
193
- if (frontMatter.slug && isDocsHomePage) {
194
- throw new Error(
195
- `The docs homepage (homePageId=${homePageId}) is not allowed to have a frontmatter slug=${frontMatter.slug} => you have to choose either homePageId or slug, not both`,
196
- );
197
- }
198
-
199
- const docSlug = isDocsHomePage
200
- ? '/'
201
- : getSlug({
202
- baseID,
203
- dirName: sourceDirName,
204
- frontmatterSlug: frontMatter.slug,
205
- stripDirNumberPrefixes: parse_number_prefixes,
206
- numberPrefixParser: options.numberPrefixParser,
207
- });
211
+ const docSlug = getSlug({
212
+ baseID,
213
+ source,
214
+ sourceDirName,
215
+ frontMatterSlug: frontMatter.slug,
216
+ stripDirNumberPrefixes: parseNumberPrefixes,
217
+ numberPrefixParser: options.numberPrefixParser,
218
+ });
208
219
 
209
- // Note: the title is used by default for page title, sidebar label, pagination buttons...
210
- // frontMatter.title should be used in priority over contentTitle (because it can contain markdown/JSX syntax)
220
+ // Note: the title is used by default for page title, sidebar label,
221
+ // pagination buttons... frontMatter.title should be used in priority over
222
+ // contentTitle (because it can contain markdown/JSX syntax)
211
223
  const title: string = frontMatter.title ?? contentTitle ?? baseID;
212
224
 
213
225
  const description: string = frontMatter.description ?? excerpt ?? '';
214
226
 
215
- const permalink = normalizeUrl([versionMetadata.versionPath, docSlug]);
227
+ const permalink = normalizeUrl([versionMetadata.path, docSlug]);
216
228
 
217
229
  function getDocEditUrl() {
218
230
  const relativeFilePath = path.relative(contentPath, filePath);
@@ -231,14 +243,15 @@ function doProcessDocMetadata({
231
243
  const isLocalized = contentPath === versionMetadata.contentPathLocalized;
232
244
  const baseVersionEditUrl =
233
245
  isLocalized && options.editLocalizedFiles
234
- ? versionMetadata.versionEditUrlLocalized
235
- : versionMetadata.versionEditUrl;
246
+ ? versionMetadata.editUrlLocalized
247
+ : versionMetadata.editUrl;
236
248
  return getEditUrl(relativeFilePath, baseVersionEditUrl);
237
- } else {
238
- return undefined;
239
249
  }
250
+ return undefined;
240
251
  }
241
252
 
253
+ const draft = isDraftForEnvironment({env, frontMatter});
254
+
242
255
  // Assign all of object properties during instantiation (if possible) for
243
256
  // NodeJS optimization.
244
257
  // Adding properties to object after instantiation will cause hidden
@@ -246,21 +259,22 @@ function doProcessDocMetadata({
246
259
  return {
247
260
  unversionedId,
248
261
  id,
249
- isDocsHomePage,
250
262
  title,
251
263
  description,
252
264
  source: aliasedSitePath(filePath, siteDir),
253
265
  sourceDirName,
254
266
  slug: docSlug,
255
267
  permalink,
268
+ draft,
256
269
  editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
270
+ tags: normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags),
257
271
  version: versionMetadata.versionName,
258
272
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
259
273
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
260
274
  formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
261
- ? new Intl.DateTimeFormat(i18n.currentLocale).format(
262
- lastUpdate.lastUpdatedAt * 1000,
263
- )
275
+ ? new Intl.DateTimeFormat(i18n.currentLocale, {
276
+ calendar: i18n.localeConfigs[i18n.currentLocale]!.calendar,
277
+ }).format(lastUpdate.lastUpdatedAt * 1000)
264
278
  : undefined,
265
279
  sidebarPosition,
266
280
  frontMatter,
@@ -272,15 +286,164 @@ export function processDocMetadata(args: {
272
286
  versionMetadata: VersionMetadata;
273
287
  context: LoadContext;
274
288
  options: MetadataOptions;
289
+ env: DocEnv;
275
290
  }): DocMetadataBase {
276
291
  try {
277
292
  return doProcessDocMetadata(args);
278
- } catch (e) {
279
- console.error(
280
- chalk.red(
281
- `Can't process doc metadatas for doc at path "${args.docFile.filePath}" in version "${args.versionMetadata.versionName}"`,
282
- ),
293
+ } catch (err) {
294
+ logger.error`Can't process doc metadata for doc at path path=${args.docFile.filePath} in version name=${args.versionMetadata.versionName}`;
295
+ throw err;
296
+ }
297
+ }
298
+
299
+ export function addDocNavigation(
300
+ docsBase: DocMetadataBase[],
301
+ sidebarsUtils: SidebarsUtils,
302
+ sidebarFilePath: string,
303
+ ): LoadedVersion['docs'] {
304
+ const docsById = createDocsByIdIndex(docsBase);
305
+
306
+ sidebarsUtils.checkSidebarsDocIds(
307
+ docsBase.flatMap(getDocIds),
308
+ sidebarFilePath,
309
+ );
310
+
311
+ // Add sidebar/next/previous to the docs
312
+ function addNavData(doc: DocMetadataBase): DocMetadata {
313
+ const navigation = sidebarsUtils.getDocNavigation(
314
+ doc.unversionedId,
315
+ doc.id,
316
+ doc.frontMatter.displayed_sidebar,
283
317
  );
284
- throw e;
318
+
319
+ const toNavigationLinkByDocId = (
320
+ docId: string | null | undefined,
321
+ type: 'prev' | 'next',
322
+ ): PropNavigationLink | undefined => {
323
+ if (!docId) {
324
+ return undefined;
325
+ }
326
+ const navDoc = docsById[docId];
327
+ if (!navDoc) {
328
+ // This could only happen if user provided the ID through front matter
329
+ throw new Error(
330
+ `Error when loading ${doc.id} in ${doc.sourceDirName}: the pagination_${type} front matter points to a non-existent ID ${docId}.`,
331
+ );
332
+ }
333
+ return toDocNavigationLink(navDoc);
334
+ };
335
+
336
+ const previous =
337
+ doc.frontMatter.pagination_prev !== undefined
338
+ ? toNavigationLinkByDocId(doc.frontMatter.pagination_prev, 'prev')
339
+ : toNavigationLink(navigation.previous, docsById);
340
+ const next =
341
+ doc.frontMatter.pagination_next !== undefined
342
+ ? toNavigationLinkByDocId(doc.frontMatter.pagination_next, 'next')
343
+ : toNavigationLink(navigation.next, docsById);
344
+
345
+ return {...doc, sidebar: navigation.sidebarName, previous, next};
285
346
  }
347
+
348
+ const docsWithNavigation = docsBase.map(addNavData);
349
+ // Sort to ensure consistent output for tests
350
+ docsWithNavigation.sort((a, b) => a.id.localeCompare(b.id));
351
+ return docsWithNavigation;
352
+ }
353
+
354
+ /**
355
+ * The "main doc" is the "version entry point"
356
+ * We browse this doc by clicking on a version:
357
+ * - the "home" doc (at '/docs/')
358
+ * - the first doc of the first sidebar
359
+ * - a random doc (if no docs are in any sidebar... edge case)
360
+ */
361
+ export function getMainDocId({
362
+ docs,
363
+ sidebarsUtils,
364
+ }: {
365
+ docs: DocMetadataBase[];
366
+ sidebarsUtils: SidebarsUtils;
367
+ }): string {
368
+ function getMainDoc(): DocMetadata {
369
+ const versionHomeDoc = docs.find((doc) => doc.slug === '/');
370
+ const firstDocIdOfFirstSidebar =
371
+ sidebarsUtils.getFirstDocIdOfFirstSidebar();
372
+ if (versionHomeDoc) {
373
+ return versionHomeDoc;
374
+ } else if (firstDocIdOfFirstSidebar) {
375
+ return docs.find(
376
+ (doc) =>
377
+ doc.id === firstDocIdOfFirstSidebar ||
378
+ doc.unversionedId === firstDocIdOfFirstSidebar,
379
+ )!;
380
+ }
381
+ return docs[0]!;
382
+ }
383
+
384
+ return getMainDoc().unversionedId;
385
+ }
386
+
387
+ // By convention, Docusaurus considers some docs are "indexes":
388
+ // - index.md
389
+ // - readme.md
390
+ // - <folder>/<folder>.md
391
+ //
392
+ // This function is the default implementation of this convention
393
+ //
394
+ // Those index docs produce a different behavior
395
+ // - Slugs do not end with a weird "/index" suffix
396
+ // - Auto-generated sidebar categories link to them as intro
397
+ export const isCategoryIndex: CategoryIndexMatcher = ({
398
+ fileName,
399
+ directories,
400
+ }): boolean => {
401
+ const eligibleDocIndexNames = [
402
+ 'index',
403
+ 'readme',
404
+ directories[0]?.toLowerCase(),
405
+ ];
406
+ return eligibleDocIndexNames.includes(fileName.toLowerCase());
407
+ };
408
+
409
+ /**
410
+ * `guides/sidebar/autogenerated.md` ->
411
+ * `'autogenerated', '.md', ['sidebar', 'guides']`
412
+ */
413
+ export function toCategoryIndexMatcherParam({
414
+ source,
415
+ sourceDirName,
416
+ }: Pick<
417
+ DocMetadataBase,
418
+ 'source' | 'sourceDirName'
419
+ >): Parameters<CategoryIndexMatcher>[0] {
420
+ // source + sourceDirName are always posix-style
421
+ return {
422
+ fileName: path.posix.parse(source).name,
423
+ extension: path.posix.parse(source).ext,
424
+ directories: sourceDirName.split(path.posix.sep).reverse(),
425
+ };
426
+ }
427
+
428
+ // Return both doc ids
429
+ // TODO legacy retro-compatibility due to old versioned sidebars using
430
+ // versioned doc ids ("id" should be removed & "versionedId" should be renamed
431
+ // to "id")
432
+ export function getDocIds(doc: DocMetadataBase): [string, string] {
433
+ return [doc.unversionedId, doc.id];
434
+ }
435
+
436
+ // Docs are indexed by both versioned and unversioned ids at the same time
437
+ // TODO legacy retro-compatibility due to old versioned sidebars using
438
+ // versioned doc ids ("id" should be removed & "versionedId" should be renamed
439
+ // to "id")
440
+ export function createDocsByIdIndex<
441
+ Doc extends {id: string; unversionedId: string},
442
+ >(docs: Doc[]): {[docId: string]: Doc} {
443
+ return Object.fromEntries(
444
+ docs.flatMap((doc) => [
445
+ [doc.unversionedId, doc],
446
+ [doc.id, doc],
447
+ ]),
448
+ );
286
449
  }
@@ -5,37 +5,47 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- /* eslint-disable camelcase */
9
-
10
8
  import {
11
- JoiFrontMatter as Joi, // Custom instance for frontmatter
9
+ JoiFrontMatter as Joi, // Custom instance for front matter
12
10
  URISchema,
11
+ FrontMatterTagsSchema,
12
+ FrontMatterTOCHeadingLevels,
13
13
  validateFrontMatter,
14
14
  } from '@docusaurus/utils-validation';
15
- import {DocFrontMatter} from './types';
15
+ import type {DocFrontMatter} from '@docusaurus/plugin-content-docs';
16
16
 
17
17
  // NOTE: we don't add any default value on purpose here
18
- // We don't want default values to magically appear in doc metadatas and props
18
+ // We don't want default values to magically appear in doc metadata and props
19
19
  // While the user did not provide those values explicitly
20
20
  // We use default values in code instead
21
21
  const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
22
22
  id: Joi.string(),
23
- title: Joi.string().allow(''), // see https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
23
+ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
24
+ title: Joi.string().allow(''),
24
25
  hide_title: Joi.boolean(),
25
26
  hide_table_of_contents: Joi.boolean(),
26
27
  keywords: Joi.array().items(Joi.string().required()),
27
28
  image: URISchema,
28
- description: Joi.string().allow(''), // see https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
29
+ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
30
+ description: Joi.string().allow(''),
29
31
  slug: Joi.string(),
30
32
  sidebar_label: Joi.string(),
31
33
  sidebar_position: Joi.number(),
34
+ sidebar_class_name: Joi.string(),
35
+ sidebar_custom_props: Joi.object().unknown(),
36
+ displayed_sidebar: Joi.string().allow(null),
37
+ tags: FrontMatterTagsSchema,
32
38
  pagination_label: Joi.string(),
33
39
  custom_edit_url: URISchema.allow('', null),
34
40
  parse_number_prefixes: Joi.boolean(),
41
+ pagination_next: Joi.string().allow(null),
42
+ pagination_prev: Joi.string().allow(null),
43
+ draft: Joi.boolean(),
44
+ ...FrontMatterTOCHeadingLevels,
35
45
  }).unknown();
36
46
 
37
- export function validateDocFrontMatter(
38
- frontMatter: Record<string, unknown>,
39
- ): DocFrontMatter {
47
+ export function validateDocFrontMatter(frontMatter: {
48
+ [key: string]: unknown;
49
+ }): DocFrontMatter {
40
50
  return validateFrontMatter(frontMatter, DocFrontMatterSchema);
41
51
  }
package/src/globalData.ts CHANGED
@@ -5,9 +5,21 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {DocMetadata, GlobalDoc, LoadedVersion, GlobalVersion} from './types';
8
+ import _ from 'lodash';
9
+ import {getMainDocId} from './docs';
10
+ import type {FullVersion} from './types';
11
+ import type {
12
+ CategoryGeneratedIndexMetadata,
13
+ DocMetadata,
14
+ } from '@docusaurus/plugin-content-docs';
15
+ import type {
16
+ GlobalVersion,
17
+ GlobalSidebar,
18
+ GlobalDoc,
19
+ } from '@docusaurus/plugin-content-docs/client';
20
+ import type {Sidebars} from './sidebars/types';
9
21
 
10
- export function toGlobalDataDoc(doc: DocMetadata): GlobalDoc {
22
+ function toGlobalDataDoc(doc: DocMetadata): GlobalDoc {
11
23
  return {
12
24
  id: doc.unversionedId,
13
25
  path: doc.permalink,
@@ -15,13 +27,51 @@ export function toGlobalDataDoc(doc: DocMetadata): GlobalDoc {
15
27
  };
16
28
  }
17
29
 
18
- export function toGlobalDataVersion(version: LoadedVersion): GlobalVersion {
30
+ function toGlobalDataGeneratedIndex(
31
+ doc: CategoryGeneratedIndexMetadata,
32
+ ): GlobalDoc {
33
+ return {
34
+ id: doc.slug,
35
+ path: doc.permalink,
36
+ sidebar: doc.sidebar,
37
+ };
38
+ }
39
+
40
+ function toGlobalSidebars(
41
+ sidebars: Sidebars,
42
+ version: FullVersion,
43
+ ): {[sidebarId: string]: GlobalSidebar} {
44
+ return _.mapValues(sidebars, (sidebar, sidebarId) => {
45
+ const firstLink = version.sidebarsUtils.getFirstLink(sidebarId);
46
+ if (!firstLink) {
47
+ return {};
48
+ }
49
+ return {
50
+ link: {
51
+ path:
52
+ firstLink.type === 'generated-index'
53
+ ? firstLink.permalink
54
+ : version.docs.find(
55
+ (doc) =>
56
+ doc.id === firstLink.id || doc.unversionedId === firstLink.id,
57
+ )!.permalink,
58
+ label: firstLink.label,
59
+ },
60
+ };
61
+ });
62
+ }
63
+
64
+ export function toGlobalDataVersion(version: FullVersion): GlobalVersion {
19
65
  return {
20
66
  name: version.versionName,
21
- label: version.versionLabel,
67
+ label: version.label,
22
68
  isLast: version.isLast,
23
- path: version.versionPath,
24
- mainDocId: version.mainDocId,
25
- docs: version.docs.map(toGlobalDataDoc),
69
+ path: version.path,
70
+ mainDocId: getMainDocId(version),
71
+ docs: version.docs
72
+ .map(toGlobalDataDoc)
73
+ .concat(version.categoryGeneratedIndices.map(toGlobalDataGeneratedIndex)),
74
+ draftIds: version.drafts.map((doc) => doc.unversionedId),
75
+ sidebars: toGlobalSidebars(version.sidebars, version),
26
76
  };
27
77
  }