@docusaurus/plugin-content-docs 2.0.0-beta.ff31de0ff → 2.0.1

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 (231) 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 +62 -72
  5. package/lib/client/docsClientUtils.d.ts +9 -28
  6. package/lib/client/docsClientUtils.js +35 -51
  7. package/lib/client/index.d.ts +81 -0
  8. package/lib/client/index.js +67 -0
  9. package/lib/constants.d.ts +4 -0
  10. package/lib/constants.js +4 -1
  11. package/lib/docs.d.ts +35 -8
  12. package/lib/docs.js +211 -78
  13. package/{src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars2.js → lib/frontMatter.d.ts} +4 -10
  14. package/lib/frontMatter.js +53 -0
  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 +137 -146
  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 +57 -29
  29. package/lib/props.d.ts +7 -2
  30. package/lib/props.js +87 -16
  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 +25 -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 +59 -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 +183 -0
  46. package/{types.d.ts → lib/sidebars/types.js} +2 -7
  47. package/lib/sidebars/utils.d.ts +55 -0
  48. package/lib/sidebars/utils.js +259 -0
  49. package/lib/sidebars/validation.d.ts +11 -0
  50. package/lib/sidebars/validation.js +143 -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 +100 -93
  57. package/lib/types.d.ts +13 -172
  58. package/lib/versions/files.d.ts +50 -0
  59. package/lib/versions/files.js +141 -0
  60. package/lib/versions/index.d.ts +36 -0
  61. package/lib/versions/index.js +154 -0
  62. package/lib/versions/validation.d.ts +17 -0
  63. package/lib/versions/validation.js +71 -0
  64. package/package.json +44 -29
  65. package/src/categoryGeneratedIndex.ts +60 -0
  66. package/src/cli.ts +94 -114
  67. package/src/client/docsClientUtils.ts +47 -84
  68. package/src/client/index.ts +158 -0
  69. package/src/constants.ts +4 -2
  70. package/src/docs.ts +294 -78
  71. package/src/frontMatter.ts +63 -0
  72. package/src/globalData.ts +57 -7
  73. package/src/index.ts +200 -204
  74. package/src/lastUpdate.ts +27 -34
  75. package/src/markdown/index.ts +10 -16
  76. package/src/markdown/linkify.ts +8 -5
  77. package/src/numberPrefix.ts +19 -26
  78. package/src/options.ts +61 -43
  79. package/src/plugin-content-docs.d.ts +575 -78
  80. package/src/props.ts +128 -23
  81. package/src/routes.ts +159 -0
  82. package/src/server-export.ts +26 -0
  83. package/src/sidebars/README.md +10 -0
  84. package/src/sidebars/generator.ts +292 -0
  85. package/src/sidebars/index.ts +118 -0
  86. package/src/sidebars/normalization.ts +91 -0
  87. package/src/sidebars/postProcessor.ts +112 -0
  88. package/src/sidebars/processor.ts +123 -0
  89. package/src/sidebars/types.ts +280 -0
  90. package/src/sidebars/utils.ts +393 -0
  91. package/src/sidebars/validation.ts +179 -0
  92. package/src/slug.ts +42 -23
  93. package/src/tags.ts +20 -0
  94. package/src/translations.ts +155 -124
  95. package/src/types.ts +17 -234
  96. package/src/versions/files.ts +216 -0
  97. package/src/versions/index.ts +246 -0
  98. package/src/versions/validation.ts +115 -0
  99. package/lib/.tsbuildinfo +0 -4673
  100. package/lib/docFrontMatter.d.ts +0 -21
  101. package/lib/docFrontMatter.js +0 -33
  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/docusaurus.config.js +0 -14
  165. package/src/__tests__/__fixtures__/site-with-doc-label/sidebars.json +0 -14
  166. package/src/__tests__/__fixtures__/versioned-site/community/team.md +0 -1
  167. package/src/__tests__/__fixtures__/versioned-site/community_sidebars.json +0 -3
  168. package/src/__tests__/__fixtures__/versioned-site/community_versioned_docs/version-1.0.0/team.md +0 -1
  169. package/src/__tests__/__fixtures__/versioned-site/community_versioned_sidebars/version-1.0.0-sidebars.json +0 -3
  170. package/src/__tests__/__fixtures__/versioned-site/community_versions.json +0 -1
  171. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +0 -4
  172. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +0 -1
  173. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/absoluteSlug.md +0 -5
  174. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/relativeSlug.md +0 -5
  175. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/resolvedSlug.md +0 -5
  176. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/tryToEscapeSlug.md +0 -5
  177. package/src/__tests__/__fixtures__/versioned-site/docusaurus.config.js +0 -18
  178. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  179. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md +0 -5
  180. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  181. package/src/__tests__/__fixtures__/versioned-site/sidebars.json +0 -10
  182. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/bar.md +0 -4
  183. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/baz.md +0 -1
  184. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +0 -1
  185. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/foo/bar.md +0 -1
  186. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +0 -1
  187. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md +0 -5
  188. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootRelativeSlug.md +0 -5
  189. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootResolvedSlug.md +0 -5
  190. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md +0 -5
  191. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md +0 -5
  192. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/relativeSlug.md +0 -5
  193. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md +0 -5
  194. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md +0 -5
  195. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
  196. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +0 -10
  197. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-withSlugs-sidebars.json +0 -5
  198. package/src/__tests__/__fixtures__/versioned-site/versions.json +0 -5
  199. package/src/__tests__/__snapshots__/cli.test.ts.snap +0 -90
  200. package/src/__tests__/__snapshots__/index.test.ts.snap +0 -1907
  201. package/src/__tests__/__snapshots__/sidebars.test.ts.snap +0 -218
  202. package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -487
  203. package/src/__tests__/cli.test.ts +0 -333
  204. package/src/__tests__/docFrontMatter.test.ts +0 -204
  205. package/src/__tests__/docs.test.ts +0 -875
  206. package/src/__tests__/index.test.ts +0 -1831
  207. package/src/__tests__/lastUpdate.test.ts +0 -68
  208. package/src/__tests__/numberPrefix.test.ts +0 -199
  209. package/src/__tests__/options.test.ts +0 -232
  210. package/src/__tests__/sidebarItemsGenerator.test.ts +0 -336
  211. package/src/__tests__/sidebars.test.ts +0 -638
  212. package/src/__tests__/slug.test.ts +0 -109
  213. package/src/__tests__/translations.test.ts +0 -159
  214. package/src/__tests__/versions.test.ts +0 -718
  215. package/src/client/__tests__/docsClientUtils.test.ts +0 -372
  216. package/src/docFrontMatter.ts +0 -53
  217. package/src/markdown/__tests__/__fixtures__/docs/doc-localized.md +0 -1
  218. package/src/markdown/__tests__/__fixtures__/docs/doc1.md +0 -13
  219. package/src/markdown/__tests__/__fixtures__/docs/doc2.md +0 -12
  220. package/src/markdown/__tests__/__fixtures__/docs/doc4.md +0 -19
  221. package/src/markdown/__tests__/__fixtures__/docs/doc5.md +0 -6
  222. package/src/markdown/__tests__/__fixtures__/docs/subdir/doc3.md +0 -3
  223. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/doc2.md +0 -7
  224. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/subdir/doc1.md +0 -3
  225. package/src/markdown/__tests__/__snapshots__/linkify.test.ts.snap +0 -82
  226. package/src/markdown/__tests__/linkify.test.ts +0 -190
  227. package/src/sidebarItemsGenerator.ts +0 -307
  228. package/src/sidebars.ts +0 -489
  229. package/src/theme/hooks/useDocs.ts +0 -99
  230. package/src/versions.ts +0 -511
  231. package/tsconfig.json +0 -9
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import path from 'path';
9
+ import {normalizeUrl, posixPath} from '@docusaurus/utils';
10
+ import {CURRENT_VERSION_NAME} from '../constants';
11
+ import {validateVersionsOptions} from './validation';
12
+ import {
13
+ getDocsDirPathLocalized,
14
+ getVersionMetadataPaths,
15
+ readVersionNames,
16
+ } from './files';
17
+ import type {
18
+ PluginOptions,
19
+ VersionBanner,
20
+ VersionMetadata,
21
+ } from '@docusaurus/plugin-content-docs';
22
+ import type {LoadContext} from '@docusaurus/types';
23
+
24
+ export type VersionContext = {
25
+ /** The version name to get banner of. */
26
+ versionName: string;
27
+ /** All versions, ordered from newest to oldest. */
28
+ versionNames: string[];
29
+ lastVersionName: string;
30
+ context: LoadContext;
31
+ options: PluginOptions;
32
+ };
33
+
34
+ function getVersionEditUrls({
35
+ contentPath,
36
+ contentPathLocalized,
37
+ context,
38
+ options,
39
+ }: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'> & {
40
+ context: LoadContext;
41
+ options: PluginOptions;
42
+ }): Pick<VersionMetadata, 'editUrl' | 'editUrlLocalized'> {
43
+ // If the user is using the functional form of editUrl,
44
+ // she has total freedom and we can't compute a "version edit url"
45
+ if (!options.editUrl || typeof options.editUrl === 'function') {
46
+ return {editUrl: undefined, editUrlLocalized: undefined};
47
+ }
48
+
49
+ const editDirPath = options.editCurrentVersion ? options.path : contentPath;
50
+ const editDirPathLocalized = options.editCurrentVersion
51
+ ? getDocsDirPathLocalized({
52
+ localizationDir: context.localizationDir,
53
+ versionName: CURRENT_VERSION_NAME,
54
+ pluginId: options.id,
55
+ })
56
+ : contentPathLocalized;
57
+
58
+ const versionPathSegment = posixPath(
59
+ path.relative(context.siteDir, path.resolve(context.siteDir, editDirPath)),
60
+ );
61
+ const versionPathSegmentLocalized = posixPath(
62
+ path.relative(
63
+ context.siteDir,
64
+ path.resolve(context.siteDir, editDirPathLocalized),
65
+ ),
66
+ );
67
+
68
+ const editUrl = normalizeUrl([options.editUrl, versionPathSegment]);
69
+
70
+ const editUrlLocalized = normalizeUrl([
71
+ options.editUrl,
72
+ versionPathSegmentLocalized,
73
+ ]);
74
+
75
+ return {editUrl, editUrlLocalized};
76
+ }
77
+
78
+ /**
79
+ * The default version banner depends on the version's relative position to the
80
+ * latest version. More recent ones are "unreleased", and older ones are
81
+ * "unmaintained".
82
+ */
83
+ export function getDefaultVersionBanner({
84
+ versionName,
85
+ versionNames,
86
+ lastVersionName,
87
+ }: VersionContext): VersionBanner | null {
88
+ // Current version: good, no banner
89
+ if (versionName === lastVersionName) {
90
+ return null;
91
+ }
92
+ // Upcoming versions: unreleased banner
93
+ if (
94
+ versionNames.indexOf(versionName) < versionNames.indexOf(lastVersionName)
95
+ ) {
96
+ return 'unreleased';
97
+ }
98
+ // Older versions: display unmaintained banner
99
+ return 'unmaintained';
100
+ }
101
+
102
+ export function getVersionBanner(
103
+ context: VersionContext,
104
+ ): VersionMetadata['banner'] {
105
+ const {versionName, options} = context;
106
+ const versionBannerOption = options.versions[versionName]?.banner;
107
+ if (versionBannerOption) {
108
+ return versionBannerOption === 'none' ? null : versionBannerOption;
109
+ }
110
+ return getDefaultVersionBanner(context);
111
+ }
112
+
113
+ export function getVersionBadge({
114
+ versionName,
115
+ versionNames,
116
+ options,
117
+ }: VersionContext): VersionMetadata['badge'] {
118
+ // If site is not versioned or only one version is included
119
+ // we don't show the version badge by default
120
+ // See https://github.com/facebook/docusaurus/issues/3362
121
+ const defaultVersionBadge = versionNames.length !== 1;
122
+ return options.versions[versionName]?.badge ?? defaultVersionBadge;
123
+ }
124
+
125
+ function getVersionClassName({
126
+ versionName,
127
+ options,
128
+ }: VersionContext): VersionMetadata['className'] {
129
+ const defaultVersionClassName = `docs-version-${versionName}`;
130
+ return options.versions[versionName]?.className ?? defaultVersionClassName;
131
+ }
132
+
133
+ function getVersionLabel({
134
+ versionName,
135
+ options,
136
+ }: VersionContext): VersionMetadata['label'] {
137
+ const defaultVersionLabel =
138
+ versionName === CURRENT_VERSION_NAME ? 'Next' : versionName;
139
+ return options.versions[versionName]?.label ?? defaultVersionLabel;
140
+ }
141
+
142
+ function getVersionPathPart({
143
+ versionName,
144
+ options,
145
+ lastVersionName,
146
+ }: VersionContext): string {
147
+ function getDefaultVersionPathPart() {
148
+ if (versionName === lastVersionName) {
149
+ return '';
150
+ }
151
+ return versionName === CURRENT_VERSION_NAME ? 'next' : versionName;
152
+ }
153
+ return options.versions[versionName]?.path ?? getDefaultVersionPathPart();
154
+ }
155
+
156
+ async function createVersionMetadata(
157
+ context: VersionContext,
158
+ ): Promise<VersionMetadata> {
159
+ const {versionName, lastVersionName, options, context: loadContext} = context;
160
+ const {sidebarFilePath, contentPath, contentPathLocalized} =
161
+ await getVersionMetadataPaths(context);
162
+ const versionPathPart = getVersionPathPart(context);
163
+
164
+ const routePath = normalizeUrl([
165
+ loadContext.baseUrl,
166
+ options.routeBasePath,
167
+ versionPathPart,
168
+ ]);
169
+
170
+ const versionEditUrls = getVersionEditUrls({
171
+ contentPath,
172
+ contentPathLocalized,
173
+ context: loadContext,
174
+ options,
175
+ });
176
+
177
+ return {
178
+ versionName,
179
+ label: getVersionLabel(context),
180
+ banner: getVersionBanner(context),
181
+ badge: getVersionBadge(context),
182
+ className: getVersionClassName(context),
183
+ path: routePath,
184
+ tagsPath: normalizeUrl([routePath, options.tagsBasePath]),
185
+ ...versionEditUrls,
186
+ isLast: versionName === lastVersionName,
187
+ routePriority: versionPathPart === '' ? -1 : undefined,
188
+ sidebarFilePath,
189
+ contentPath,
190
+ contentPathLocalized,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Filter versions according to provided options (i.e. `onlyIncludeVersions`).
196
+ *
197
+ * Note: we preserve the order in which versions are provided; the order of the
198
+ * `onlyIncludeVersions` array does not matter
199
+ */
200
+ export function filterVersions(
201
+ versionNamesUnfiltered: string[],
202
+ options: PluginOptions,
203
+ ): string[] {
204
+ if (options.onlyIncludeVersions) {
205
+ return versionNamesUnfiltered.filter((name) =>
206
+ options.onlyIncludeVersions!.includes(name),
207
+ );
208
+ }
209
+ return versionNamesUnfiltered;
210
+ }
211
+
212
+ function getLastVersionName({
213
+ versionNames,
214
+ options,
215
+ }: Pick<VersionContext, 'versionNames' | 'options'>) {
216
+ return (
217
+ options.lastVersion ??
218
+ versionNames.find((name) => name !== CURRENT_VERSION_NAME) ??
219
+ CURRENT_VERSION_NAME
220
+ );
221
+ }
222
+
223
+ export async function readVersionsMetadata({
224
+ context,
225
+ options,
226
+ }: {
227
+ context: LoadContext;
228
+ options: PluginOptions;
229
+ }): Promise<VersionMetadata[]> {
230
+ const allVersionNames = await readVersionNames(context.siteDir, options);
231
+ validateVersionsOptions(allVersionNames, options);
232
+ const versionNames = filterVersions(allVersionNames, options);
233
+ const lastVersionName = getLastVersionName({versionNames, options});
234
+ const versionsMetadata = await Promise.all(
235
+ versionNames.map((versionName) =>
236
+ createVersionMetadata({
237
+ versionName,
238
+ versionNames,
239
+ lastVersionName,
240
+ context,
241
+ options,
242
+ }),
243
+ ),
244
+ );
245
+ return versionsMetadata;
246
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import _ from 'lodash';
9
+ import type {VersionsOptions} from '@docusaurus/plugin-content-docs';
10
+
11
+ export function validateVersionName(name: unknown): asserts name is string {
12
+ if (typeof name !== 'string') {
13
+ throw new Error(
14
+ `Versions should be strings. Found type "${typeof name}" for version ${JSON.stringify(
15
+ name,
16
+ )}.`,
17
+ );
18
+ }
19
+ if (!name.trim()) {
20
+ throw new Error(
21
+ `Invalid version name "${name}": version name must contain at least one non-whitespace character.`,
22
+ );
23
+ }
24
+ const errors: [RegExp, string][] = [
25
+ [/[/\\]/, 'should not include slash (/) or backslash (\\)'],
26
+ [/.{33,}/, 'cannot be longer than 32 characters'],
27
+ // eslint-disable-next-line no-control-regex
28
+ [/[<>:"|?*\x00-\x1F]/, 'should be a valid file path'],
29
+ [/^\.\.?$/, 'should not be "." or ".."'],
30
+ ];
31
+
32
+ errors.forEach(([pattern, message]) => {
33
+ if (pattern.test(name)) {
34
+ throw new Error(
35
+ `Invalid version name "${name}": version name ${message}.`,
36
+ );
37
+ }
38
+ });
39
+ }
40
+
41
+ export function validateVersionNames(
42
+ names: unknown,
43
+ ): asserts names is string[] {
44
+ if (!Array.isArray(names)) {
45
+ throw new Error(
46
+ `The versions file should contain an array of version names! Found content: ${JSON.stringify(
47
+ names,
48
+ )}`,
49
+ );
50
+ }
51
+
52
+ names.forEach(validateVersionName);
53
+ }
54
+
55
+ /**
56
+ * @throws Throws for one of the following invalid options:
57
+ * - `lastVersion` is non-existent
58
+ * - `versions` includes unknown keys
59
+ * - `onlyIncludeVersions` is empty, contains unknown names, or doesn't include
60
+ * `latestVersion` (if provided)
61
+ */
62
+ export function validateVersionsOptions(
63
+ availableVersionNames: string[],
64
+ options: VersionsOptions,
65
+ ): void {
66
+ const availableVersionNamesMsg = `Available version names are: ${availableVersionNames.join(
67
+ ', ',
68
+ )}`;
69
+ if (
70
+ options.lastVersion &&
71
+ !availableVersionNames.includes(options.lastVersion)
72
+ ) {
73
+ throw new Error(
74
+ `Docs option lastVersion: ${options.lastVersion} is invalid. ${availableVersionNamesMsg}`,
75
+ );
76
+ }
77
+ const unknownVersionConfigNames = _.difference(
78
+ Object.keys(options.versions),
79
+ availableVersionNames,
80
+ );
81
+ if (unknownVersionConfigNames.length > 0) {
82
+ throw new Error(
83
+ `Invalid docs option "versions": unknown versions (${unknownVersionConfigNames.join(
84
+ ',',
85
+ )}) found. ${availableVersionNamesMsg}`,
86
+ );
87
+ }
88
+
89
+ if (options.onlyIncludeVersions) {
90
+ if (options.onlyIncludeVersions.length === 0) {
91
+ throw new Error(
92
+ `Invalid docs option "onlyIncludeVersions": an empty array is not allowed, at least one version is needed.`,
93
+ );
94
+ }
95
+ const unknownOnlyIncludeVersionNames = _.difference(
96
+ options.onlyIncludeVersions,
97
+ availableVersionNames,
98
+ );
99
+ if (unknownOnlyIncludeVersionNames.length > 0) {
100
+ throw new Error(
101
+ `Invalid docs option "onlyIncludeVersions": unknown versions (${unknownOnlyIncludeVersionNames.join(
102
+ ',',
103
+ )}) found. ${availableVersionNamesMsg}`,
104
+ );
105
+ }
106
+ if (
107
+ options.lastVersion &&
108
+ !options.onlyIncludeVersions.includes(options.lastVersion)
109
+ ) {
110
+ throw new Error(
111
+ `Invalid docs option "lastVersion": if you use both the "onlyIncludeVersions" and "lastVersion" options, then "lastVersion" must be present in the provided "onlyIncludeVersions" array.`,
112
+ );
113
+ }
114
+ }
115
+ }