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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/lib/categoryGeneratedIndex.d.ts +12 -0
  2. package/lib/categoryGeneratedIndex.js +39 -0
  3. package/lib/cli.d.ts +2 -2
  4. package/lib/cli.js +40 -52
  5. package/lib/client/docsClientUtils.d.ts +3 -25
  6. package/lib/client/docsClientUtils.js +27 -33
  7. package/lib/{theme/hooks/useDocs.d.ts → client/index.d.ts} +1 -2
  8. package/lib/client/index.js +75 -0
  9. package/lib/docFrontMatter.d.ts +1 -14
  10. package/lib/docFrontMatter.js +13 -6
  11. package/lib/docs.d.ts +40 -4
  12. package/lib/docs.js +170 -54
  13. package/lib/globalData.d.ts +5 -1
  14. package/lib/globalData.js +35 -2
  15. package/lib/index.d.ts +4 -3
  16. package/lib/index.js +124 -136
  17. package/lib/lastUpdate.js +16 -29
  18. package/lib/markdown/index.d.ts +3 -6
  19. package/lib/markdown/index.js +3 -3
  20. package/lib/markdown/linkify.d.ts +1 -1
  21. package/lib/markdown/linkify.js +3 -3
  22. package/lib/numberPrefix.d.ts +1 -1
  23. package/lib/numberPrefix.js +7 -6
  24. package/lib/options.d.ts +3 -3
  25. package/lib/options.js +52 -17
  26. package/lib/props.d.ts +7 -2
  27. package/lib/props.js +71 -14
  28. package/lib/routes.d.ts +28 -0
  29. package/lib/routes.js +110 -0
  30. package/lib/server-export.d.ts +8 -0
  31. package/lib/server-export.js +23 -0
  32. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +1 -6
  33. package/lib/sidebars/generator.js +190 -0
  34. package/lib/sidebars/index.d.ts +13 -0
  35. package/lib/sidebars/index.js +88 -0
  36. package/lib/sidebars/normalization.d.ts +13 -0
  37. package/lib/sidebars/normalization.js +55 -0
  38. package/lib/sidebars/postProcessor.d.ts +8 -0
  39. package/lib/sidebars/postProcessor.js +72 -0
  40. package/lib/sidebars/processor.d.ts +8 -0
  41. package/lib/sidebars/processor.js +79 -0
  42. package/lib/sidebars/types.d.ts +166 -0
  43. package/{src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars2.js → lib/sidebars/types.js} +2 -10
  44. package/lib/sidebars/utils.d.ts +43 -0
  45. package/lib/sidebars/utils.js +265 -0
  46. package/lib/sidebars/validation.d.ts +9 -0
  47. package/lib/sidebars/validation.js +137 -0
  48. package/lib/slug.d.ts +6 -4
  49. package/lib/slug.js +29 -18
  50. package/{src/__tests__/__fixtures__/site-with-doc-label/docusaurus.config.js → lib/tags.d.ts} +2 -8
  51. package/lib/tags.js +21 -0
  52. package/lib/translations.d.ts +2 -2
  53. package/lib/translations.js +87 -44
  54. package/lib/types.d.ts +55 -128
  55. package/lib/versions.d.ts +29 -4
  56. package/lib/versions.js +131 -89
  57. package/package.json +30 -26
  58. package/src/categoryGeneratedIndex.ts +59 -0
  59. package/src/cli.ts +48 -62
  60. package/src/client/docsClientUtils.ts +36 -71
  61. package/src/{theme/hooks/useDocs.ts → client/index.ts} +15 -10
  62. package/{types.d.ts → src/deps.d.ts} +0 -0
  63. package/src/docFrontMatter.ts +17 -22
  64. package/src/docs.ts +229 -45
  65. package/src/globalData.ts +53 -2
  66. package/src/index.ts +168 -177
  67. package/src/lastUpdate.ts +14 -33
  68. package/src/markdown/index.ts +9 -13
  69. package/src/markdown/linkify.ts +2 -2
  70. package/src/numberPrefix.ts +11 -8
  71. package/src/options.ts +59 -29
  72. package/src/plugin-content-docs.d.ts +256 -40
  73. package/src/props.ts +105 -21
  74. package/src/routes.ts +185 -0
  75. package/src/server-export.ts +24 -0
  76. package/src/sidebars/README.md +9 -0
  77. package/src/sidebars/generator.ts +263 -0
  78. package/src/sidebars/index.ts +113 -0
  79. package/src/sidebars/normalization.ts +85 -0
  80. package/src/sidebars/postProcessor.ts +94 -0
  81. package/src/sidebars/processor.ts +126 -0
  82. package/src/sidebars/types.ts +273 -0
  83. package/src/sidebars/utils.ts +392 -0
  84. package/src/sidebars/validation.ts +173 -0
  85. package/src/slug.ts +40 -22
  86. package/src/tags.ts +19 -0
  87. package/src/translations.ts +121 -62
  88. package/src/types.ts +62 -183
  89. package/src/versions.ts +202 -107
  90. package/lib/.tsbuildinfo +0 -4717
  91. package/lib/sidebarItemsGenerator.js +0 -211
  92. package/lib/sidebars.d.ts +0 -42
  93. package/lib/sidebars.js +0 -309
  94. package/lib/theme/hooks/useDocs.js +0 -72
  95. package/src/__tests__/__fixtures__/bad-id-site/docs/invalid-id.md +0 -5
  96. package/src/__tests__/__fixtures__/bad-slug-on-doc-home-site/docs/docWithSlug.md +0 -5
  97. package/src/__tests__/__fixtures__/empty-site/docusaurus.config.js +0 -16
  98. package/src/__tests__/__fixtures__/empty-site/sidebars.json +0 -1
  99. package/src/__tests__/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -34
  100. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -11
  101. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -11
  102. package/src/__tests__/__fixtures__/sidebars/sidebars-category.js +0 -44
  103. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -20
  104. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed.json +0 -21
  105. package/src/__tests__/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -10
  106. package/src/__tests__/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -20
  107. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -11
  108. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -11
  109. package/src/__tests__/__fixtures__/sidebars/sidebars-link.json +0 -11
  110. package/src/__tests__/__fixtures__/sidebars/sidebars-unknown-type.json +0 -14
  111. package/src/__tests__/__fixtures__/sidebars/sidebars-wrong-field.json +0 -20
  112. package/src/__tests__/__fixtures__/sidebars/sidebars.json +0 -20
  113. package/src/__tests__/__fixtures__/simple-site/docs/foo/bar.md +0 -69
  114. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +0 -67
  115. package/src/__tests__/__fixtures__/simple-site/docs/headingAsTitle.md +0 -1
  116. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +0 -52
  117. package/src/__tests__/__fixtures__/simple-site/docs/ipsum.md +0 -5
  118. package/src/__tests__/__fixtures__/simple-site/docs/lorem.md +0 -6
  119. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +0 -5
  120. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +0 -5
  121. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +0 -5
  122. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +0 -5
  123. package/src/__tests__/__fixtures__/simple-site/docs/slugs/absoluteSlug.md +0 -5
  124. package/src/__tests__/__fixtures__/simple-site/docs/slugs/relativeSlug.md +0 -5
  125. package/src/__tests__/__fixtures__/simple-site/docs/slugs/resolvedSlug.md +0 -5
  126. package/src/__tests__/__fixtures__/simple-site/docs/slugs/tryToEscapeSlug.md +0 -5
  127. package/src/__tests__/__fixtures__/simple-site/docusaurus.config.js +0 -14
  128. package/src/__tests__/__fixtures__/simple-site/sidebars.json +0 -23
  129. package/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json +0 -7
  130. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/0-getting-started.md +0 -3
  131. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/1-installation.md +0 -3
  132. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/00_api-overview.md +0 -3
  133. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/0 --- Client API.md +0 -1
  134. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/1 --- Server API.md +0 -1
  135. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/0. Plugin API.md +0 -1
  136. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/1. Theme API.md +0 -1
  137. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/_category_.yml +0 -1
  138. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/03_api-end.md +0 -3
  139. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/_category_.json +0 -3
  140. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/0-guide2.5.md +0 -8
  141. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/02-guide2.md +0 -7
  142. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/_category_.json +0 -3
  143. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/a-guide4.md +0 -7
  144. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/b-guide5.md +0 -7
  145. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/guide3.md +0 -8
  146. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/z-guide1.md +0 -8
  147. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docusaurus.config.js +0 -14
  148. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars.js +0 -23
  149. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +0 -7
  150. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-2.md +0 -8
  151. package/src/__tests__/__fixtures__/site-with-doc-label/sidebars.json +0 -14
  152. package/src/__tests__/__fixtures__/versioned-site/community/team.md +0 -1
  153. package/src/__tests__/__fixtures__/versioned-site/community_sidebars.json +0 -3
  154. package/src/__tests__/__fixtures__/versioned-site/community_versioned_docs/version-1.0.0/team.md +0 -1
  155. package/src/__tests__/__fixtures__/versioned-site/community_versioned_sidebars/version-1.0.0-sidebars.json +0 -3
  156. package/src/__tests__/__fixtures__/versioned-site/community_versions.json +0 -1
  157. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +0 -4
  158. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +0 -1
  159. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/absoluteSlug.md +0 -5
  160. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/relativeSlug.md +0 -5
  161. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/resolvedSlug.md +0 -5
  162. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/tryToEscapeSlug.md +0 -5
  163. package/src/__tests__/__fixtures__/versioned-site/docusaurus.config.js +0 -18
  164. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  165. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md +0 -5
  166. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  167. package/src/__tests__/__fixtures__/versioned-site/sidebars.json +0 -10
  168. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/bar.md +0 -4
  169. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/baz.md +0 -1
  170. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +0 -1
  171. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/foo/bar.md +0 -1
  172. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +0 -1
  173. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md +0 -5
  174. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootRelativeSlug.md +0 -5
  175. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootResolvedSlug.md +0 -5
  176. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md +0 -5
  177. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md +0 -5
  178. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/relativeSlug.md +0 -5
  179. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md +0 -5
  180. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md +0 -5
  181. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
  182. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +0 -10
  183. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-withSlugs-sidebars.json +0 -5
  184. package/src/__tests__/__fixtures__/versioned-site/versions.json +0 -5
  185. package/src/__tests__/__snapshots__/cli.test.ts.snap +0 -90
  186. package/src/__tests__/__snapshots__/index.test.ts.snap +0 -1907
  187. package/src/__tests__/__snapshots__/sidebars.test.ts.snap +0 -218
  188. package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -487
  189. package/src/__tests__/cli.test.ts +0 -333
  190. package/src/__tests__/docFrontMatter.test.ts +0 -204
  191. package/src/__tests__/docs.test.ts +0 -875
  192. package/src/__tests__/index.test.ts +0 -1831
  193. package/src/__tests__/lastUpdate.test.ts +0 -68
  194. package/src/__tests__/numberPrefix.test.ts +0 -199
  195. package/src/__tests__/options.test.ts +0 -232
  196. package/src/__tests__/sidebarItemsGenerator.test.ts +0 -336
  197. package/src/__tests__/sidebars.test.ts +0 -638
  198. package/src/__tests__/slug.test.ts +0 -109
  199. package/src/__tests__/translations.test.ts +0 -159
  200. package/src/__tests__/versions.test.ts +0 -718
  201. package/src/client/__tests__/docsClientUtils.test.ts +0 -372
  202. package/src/markdown/__tests__/__fixtures__/docs/doc-localized.md +0 -1
  203. package/src/markdown/__tests__/__fixtures__/docs/doc1.md +0 -13
  204. package/src/markdown/__tests__/__fixtures__/docs/doc2.md +0 -12
  205. package/src/markdown/__tests__/__fixtures__/docs/doc4.md +0 -19
  206. package/src/markdown/__tests__/__fixtures__/docs/doc5.md +0 -6
  207. package/src/markdown/__tests__/__fixtures__/docs/subdir/doc3.md +0 -3
  208. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/doc2.md +0 -7
  209. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/subdir/doc1.md +0 -3
  210. package/src/markdown/__tests__/__snapshots__/linkify.test.ts.snap +0 -82
  211. package/src/markdown/__tests__/linkify.test.ts +0 -190
  212. package/src/sidebarItemsGenerator.ts +0 -307
  213. package/src/sidebars.ts +0 -489
  214. package/tsconfig.json +0 -9
package/src/cli.ts CHANGED
@@ -12,15 +12,15 @@ import {
12
12
  } from './versions';
13
13
  import fs from 'fs-extra';
14
14
  import path from 'path';
15
- import {
15
+ import type {
16
16
  PathOptions,
17
- UnprocessedSidebarItem,
18
- UnprocessedSidebars,
19
- } from './types';
20
- import {loadSidebars} from './sidebars';
21
- import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
17
+ SidebarOptions,
18
+ } from '@docusaurus/plugin-content-docs';
19
+ import {loadSidebarsFileUnsafe, resolveSidebarPathOption} from './sidebars';
20
+ import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
21
+ import logger from '@docusaurus/logger';
22
22
 
23
- function createVersionedSidebarFile({
23
+ async function createVersionedSidebarFile({
24
24
  siteDir,
25
25
  pluginId,
26
26
  sidebarPath,
@@ -32,83 +32,57 @@ function createVersionedSidebarFile({
32
32
  version: string;
33
33
  }) {
34
34
  // Load current sidebar and create a new versioned sidebars file (if needed).
35
- const loadedSidebars = loadSidebars(sidebarPath);
35
+ // Note: we don't need the sidebars file to be normalized: it's ok to let
36
+ // plugin option changes to impact older, versioned sidebars
37
+ // We don't validate here, assuming the user has already built the version
38
+ const sidebars = await loadSidebarsFileUnsafe(sidebarPath);
36
39
 
37
- // Do not create a useless versioned sidebars file if sidebars file is empty or sidebars are disabled/false)
38
- const shouldCreateVersionedSidebarFile =
39
- Object.keys(loadedSidebars).length > 0;
40
+ // Do not create a useless versioned sidebars file if sidebars file is empty
41
+ // or sidebars are disabled/false)
42
+ const shouldCreateVersionedSidebarFile = Object.keys(sidebars).length > 0;
40
43
 
41
44
  if (shouldCreateVersionedSidebarFile) {
42
- // TODO @slorber: this "version prefix" in versioned sidebars looks like a bad idea to me
43
- // TODO try to get rid of it
44
- // Transform id in original sidebar to versioned id.
45
- const normalizeItem = (
46
- item: UnprocessedSidebarItem,
47
- ): UnprocessedSidebarItem => {
48
- switch (item.type) {
49
- case 'category':
50
- return {...item, items: item.items.map(normalizeItem)};
51
- case 'ref':
52
- case 'doc':
53
- return {
54
- type: item.type,
55
- id: `version-${version}/${item.id}`,
56
- };
57
- default:
58
- return item;
59
- }
60
- };
61
-
62
- const versionedSidebar: UnprocessedSidebars = Object.entries(
63
- loadedSidebars,
64
- ).reduce((acc: UnprocessedSidebars, [sidebarId, sidebarItems]) => {
65
- const newVersionedSidebarId = `version-${version}/${sidebarId}`;
66
- acc[newVersionedSidebarId] = sidebarItems.map(normalizeItem);
67
- return acc;
68
- }, {});
69
-
70
45
  const versionedSidebarsDir = getVersionedSidebarsDirPath(siteDir, pluginId);
71
46
  const newSidebarFile = path.join(
72
47
  versionedSidebarsDir,
73
48
  `version-${version}-sidebars.json`,
74
49
  );
75
- fs.ensureDirSync(path.dirname(newSidebarFile));
76
- fs.writeFileSync(
50
+ await fs.ensureDir(path.dirname(newSidebarFile));
51
+ await fs.writeFile(
77
52
  newSidebarFile,
78
- `${JSON.stringify(versionedSidebar, null, 2)}\n`,
53
+ `${JSON.stringify(sidebars, null, 2)}\n`,
79
54
  'utf8',
80
55
  );
81
56
  }
82
57
  }
83
58
 
84
59
  // Tests depend on non-default export for mocking.
85
- // eslint-disable-next-line import/prefer-default-export
86
- export function cliDocsVersionCommand(
60
+ export async function cliDocsVersionCommand(
87
61
  version: string | null | undefined,
88
62
  siteDir: string,
89
63
  pluginId: string,
90
- options: PathOptions,
91
- ): void {
64
+ options: PathOptions & SidebarOptions,
65
+ ): Promise<void> {
92
66
  // It wouldn't be very user-friendly to show a [default] log prefix,
93
67
  // so we use [docs] instead of [default]
94
68
  const pluginIdLogPrefix =
95
- pluginId === DEFAULT_PLUGIN_ID ? '[docs] ' : `[${pluginId}] `;
69
+ pluginId === DEFAULT_PLUGIN_ID ? '[docs]' : `[${pluginId}]`;
96
70
 
97
71
  if (!version) {
98
72
  throw new Error(
99
- `${pluginIdLogPrefix}No version tag specified!. Pass the version you wish to create as an argument. Ex: 1.0.0`,
73
+ `${pluginIdLogPrefix}: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0.`,
100
74
  );
101
75
  }
102
76
 
103
77
  if (version.includes('/') || version.includes('\\')) {
104
78
  throw new Error(
105
- `${pluginIdLogPrefix}Invalid version tag specified! Do not include slash (/) or (\\). Try something like: 1.0.0`,
79
+ `${pluginIdLogPrefix}: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.`,
106
80
  );
107
81
  }
108
82
 
109
83
  if (version.length > 32) {
110
84
  throw new Error(
111
- `${pluginIdLogPrefix}Invalid version tag specified! Length must <= 32 characters. Try something like: 1.0.0`,
85
+ `${pluginIdLogPrefix}: invalid version tag specified! Length cannot exceed 32 characters. Try something like: 1.0.0.`,
112
86
  );
113
87
  }
114
88
 
@@ -117,27 +91,27 @@ export function cliDocsVersionCommand(
117
91
  // eslint-disable-next-line no-control-regex
118
92
  if (/[<>:"|?*\x00-\x1F]/g.test(version)) {
119
93
  throw new Error(
120
- `${pluginIdLogPrefix}Invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0`,
94
+ `${pluginIdLogPrefix}: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0.`,
121
95
  );
122
96
  }
123
97
 
124
98
  if (/^\.\.?$/.test(version)) {
125
99
  throw new Error(
126
- `${pluginIdLogPrefix}Invalid version tag specified! Do not name your version "." or "..". Try something like: 1.0.0`,
100
+ `${pluginIdLogPrefix}: invalid version tag specified! Do not name your version "." or "..". Try something like: 1.0.0.`,
127
101
  );
128
102
  }
129
103
 
130
104
  // Load existing versions.
131
105
  let versions = [];
132
106
  const versionsJSONFile = getVersionsFilePath(siteDir, pluginId);
133
- if (fs.existsSync(versionsJSONFile)) {
134
- versions = JSON.parse(fs.readFileSync(versionsJSONFile, 'utf8'));
107
+ if (await fs.pathExists(versionsJSONFile)) {
108
+ versions = JSON.parse(await fs.readFile(versionsJSONFile, 'utf8'));
135
109
  }
136
110
 
137
111
  // Check if version already exists.
138
112
  if (versions.includes(version)) {
139
113
  throw new Error(
140
- `${pluginIdLogPrefix}This version already exists!. Use a version tag that does not already exist.`,
114
+ `${pluginIdLogPrefix}: this version already exists! Use a version tag that does not already exist.`,
141
115
  );
142
116
  }
143
117
 
@@ -145,20 +119,32 @@ export function cliDocsVersionCommand(
145
119
 
146
120
  // Copy docs files.
147
121
  const docsDir = path.join(siteDir, docsPath);
148
- if (fs.existsSync(docsDir) && fs.readdirSync(docsDir).length > 0) {
122
+
123
+ if (
124
+ (await fs.pathExists(docsDir)) &&
125
+ (await fs.readdir(docsDir)).length > 0
126
+ ) {
149
127
  const versionedDir = getVersionedDocsDirPath(siteDir, pluginId);
150
128
  const newVersionDir = path.join(versionedDir, `version-${version}`);
151
- fs.copySync(docsDir, newVersionDir);
129
+ await fs.copy(docsDir, newVersionDir);
152
130
  } else {
153
- throw new Error(`${pluginIdLogPrefix}There is no docs to version !`);
131
+ throw new Error(`${pluginIdLogPrefix}: there is no docs to version!`);
154
132
  }
155
133
 
156
- createVersionedSidebarFile({siteDir, pluginId, version, sidebarPath});
134
+ await createVersionedSidebarFile({
135
+ siteDir,
136
+ pluginId,
137
+ version,
138
+ sidebarPath: resolveSidebarPathOption(siteDir, sidebarPath),
139
+ });
157
140
 
158
141
  // Update versions.json file.
159
142
  versions.unshift(version);
160
- fs.ensureDirSync(path.dirname(versionsJSONFile));
161
- fs.writeFileSync(versionsJSONFile, `${JSON.stringify(versions, null, 2)}\n`);
143
+ await fs.ensureDir(path.dirname(versionsJSONFile));
144
+ await fs.writeFile(
145
+ versionsJSONFile,
146
+ `${JSON.stringify(versions, null, 2)}\n`,
147
+ );
162
148
 
163
- console.log(`${pluginIdLogPrefix}Version ${version} created!`);
149
+ logger.success`name=${pluginIdLogPrefix}: version name=${version} created!`;
164
150
  }
@@ -7,49 +7,37 @@
7
7
 
8
8
  import {matchPath} from '@docusaurus/router';
9
9
 
10
- import {GlobalPluginData, GlobalVersion, GlobalDoc} from '../types';
10
+ import type {
11
+ GlobalPluginData,
12
+ GlobalVersion,
13
+ GlobalDoc,
14
+ GetActivePluginOptions,
15
+ ActivePlugin,
16
+ ActiveDocContext,
17
+ DocVersionSuggestions,
18
+ } from '@docusaurus/plugin-content-docs/client';
11
19
 
12
20
  // This code is not part of the api surface, not in ./theme on purpose
13
21
 
14
- // Short/convenient type aliases
15
- type Version = GlobalVersion;
16
- type Doc = GlobalDoc;
17
-
18
- export type ActivePlugin = {
19
- pluginId: string;
20
- pluginData: GlobalPluginData;
21
- };
22
-
23
- export type GetActivePluginOptions = {failfast?: boolean};
24
-
25
22
  // get the data of the plugin that is currently "active"
26
23
  // ie the docs of that plugin are currently browsed
27
24
  // it is useful to support multiple docs plugin instances
28
- export function getActivePlugin(
29
- allPluginDatas: Record<string, GlobalPluginData>,
30
- pathname: string,
31
- options: {failfast: true}, // use fail-fast option if you know for sure one plugin instance is active
32
- ): ActivePlugin;
33
- export function getActivePlugin(
34
- allPluginDatas: Record<string, GlobalPluginData>,
35
- pathname: string,
36
- options?: GetActivePluginOptions,
37
- ): ActivePlugin | undefined;
38
-
39
25
  export function getActivePlugin(
40
26
  allPluginDatas: Record<string, GlobalPluginData>,
41
27
  pathname: string,
42
28
  options: GetActivePluginOptions = {},
43
29
  ): ActivePlugin | undefined {
44
- const activeEntry = Object.entries(allPluginDatas).find(
45
- ([_id, pluginData]) => {
46
- return !!matchPath(pathname, {
47
- path: pluginData.path,
48
- exact: false,
49
- strict: false,
50
- });
51
- },
52
- );
30
+ const activeEntry = Object.entries(allPluginDatas)
31
+ // Route sorting: '/android/foo' should match '/android' instead of '/'
32
+ .sort((a, b) => b[1].path.localeCompare(a[1].path))
33
+ .find(
34
+ ([, pluginData]) =>
35
+ !!matchPath(pathname, {
36
+ path: pluginData.path,
37
+ exact: false,
38
+ strict: false,
39
+ }),
40
+ );
53
41
 
54
42
  const activePlugin: ActivePlugin | undefined = activeEntry
55
43
  ? {pluginId: activeEntry[0], pluginData: activeEntry[1]}
@@ -57,7 +45,7 @@ export function getActivePlugin(
57
45
 
58
46
  if (!activePlugin && options.failfast) {
59
47
  throw new Error(
60
- `Can't find active docs plugin for pathname=${pathname}, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
48
+ `Can't find active docs plugin for "${pathname}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
61
49
  allPluginDatas,
62
50
  )
63
51
  .map((plugin) => plugin.path)
@@ -68,36 +56,30 @@ export function getActivePlugin(
68
56
  return activePlugin;
69
57
  }
70
58
 
71
- export type ActiveDocContext = {
72
- activeVersion?: Version;
73
- activeDoc?: Doc;
74
- alternateDocVersions: Record<string, Doc>;
75
- };
76
-
77
- export const getLatestVersion = (data: GlobalPluginData): Version => {
78
- return data.versions.find((version) => version.isLast)!;
79
- };
59
+ export const getLatestVersion = (data: GlobalPluginData): GlobalVersion =>
60
+ data.versions.find((version) => version.isLast)!;
80
61
 
81
62
  // Note: return undefined on doc-unrelated pages,
82
63
  // because there's no version currently considered as active
83
64
  export const getActiveVersion = (
84
65
  data: GlobalPluginData,
85
66
  pathname: string,
86
- ): Version | undefined => {
67
+ ): GlobalVersion | undefined => {
87
68
  const lastVersion = getLatestVersion(data);
88
69
  // Last version is a route like /docs/*,
89
- // we need to try to match it last or it would match /docs/version-1.0/* as well
70
+ // we need to match it last or it would match /docs/version-1.0/* as well
90
71
  const orderedVersionsMetadata = [
91
72
  ...data.versions.filter((version) => version !== lastVersion),
92
73
  lastVersion,
93
74
  ];
94
- return orderedVersionsMetadata.find((version) => {
95
- return !!matchPath(pathname, {
96
- path: version.path,
97
- exact: false,
98
- strict: false,
99
- });
100
- });
75
+ return orderedVersionsMetadata.find(
76
+ (version) =>
77
+ !!matchPath(pathname, {
78
+ path: version.path,
79
+ exact: false,
80
+ strict: false,
81
+ }),
82
+ );
101
83
  };
102
84
 
103
85
  export const getActiveDocContext = (
@@ -139,30 +121,13 @@ export const getActiveDocContext = (
139
121
  };
140
122
  };
141
123
 
142
- export type DocVersionSuggestions = {
143
- // suggest the same doc, in latest version (if exist)
144
- latestDocSuggestion?: GlobalDoc;
145
- // suggest the latest version
146
- latestVersionSuggestion?: GlobalVersion;
147
- };
148
-
149
124
  export const getDocVersionSuggestions = (
150
125
  data: GlobalPluginData,
151
126
  pathname: string,
152
127
  ): DocVersionSuggestions => {
153
128
  const latestVersion = getLatestVersion(data);
154
129
  const activeDocContext = getActiveDocContext(data, pathname);
155
-
156
- // We only suggest another doc/version if user is not using the latest version
157
- const isNotOnLatestVersion = activeDocContext.activeVersion !== latestVersion;
158
-
159
- const latestDocSuggestion: GlobalDoc | undefined = isNotOnLatestVersion
160
- ? activeDocContext?.alternateDocVersions[latestVersion.name]
161
- : undefined;
162
-
163
- const latestVersionSuggestion = isNotOnLatestVersion
164
- ? latestVersion
165
- : undefined;
166
-
167
- return {latestDocSuggestion, latestVersionSuggestion};
130
+ const latestDocSuggestion: GlobalDoc | undefined =
131
+ activeDocContext?.alternateDocVersions[latestVersion.name];
132
+ return {latestDocSuggestion, latestVersionSuggestion: latestVersion};
168
133
  };
@@ -6,33 +6,38 @@
6
6
  */
7
7
 
8
8
  import {useLocation} from '@docusaurus/router';
9
- import useGlobalData, {
10
- // useAllPluginInstancesData,
11
- usePluginData,
12
- } from '@docusaurus/useGlobalData';
9
+ import useGlobalData, {usePluginData} from '@docusaurus/useGlobalData';
13
10
 
14
- import {GlobalPluginData, GlobalVersion} from '../../types';
15
11
  import {
16
12
  getActivePlugin,
17
13
  getLatestVersion,
18
14
  getActiveVersion,
19
15
  getActiveDocContext,
20
16
  getDocVersionSuggestions,
17
+ } from './docsClientUtils';
18
+ import type {
19
+ GlobalPluginData,
20
+ GlobalVersion,
21
21
  ActivePlugin,
22
22
  ActiveDocContext,
23
23
  DocVersionSuggestions,
24
24
  GetActivePluginOptions,
25
- } from '../../client/docsClientUtils';
25
+ } from '@docusaurus/plugin-content-docs/client';
26
26
 
27
- // Not using useAllPluginInstancesData() because in blog-only mode, docs hooks are still used by the theme
28
- // We need a fail-safe fallback when the docs plugin is not in use
27
+ // Important to use a constant object to avoid React useEffect executions etc.
28
+ // see https://github.com/facebook/docusaurus/issues/5089
29
+ const StableEmptyObject = {};
30
+
31
+ // Not using useAllPluginInstancesData() because in blog-only mode, docs hooks
32
+ // are still used by the theme. We need a fail-safe fallback when the docs
33
+ // plugin is not in use
29
34
  export const useAllDocsData = (): Record<string, GlobalPluginData> =>
30
- // useAllPluginInstancesData('docusaurus-plugin-content-docs');
31
- useGlobalData()['docusaurus-plugin-content-docs'] ?? {};
35
+ useGlobalData()['docusaurus-plugin-content-docs'] ?? StableEmptyObject;
32
36
 
33
37
  export const useDocsData = (pluginId: string | undefined): GlobalPluginData =>
34
38
  usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
35
39
 
40
+ // TODO this feature should be provided by docusaurus core
36
41
  export const useActivePlugin = (
37
42
  options: GetActivePluginOptions = {},
38
43
  ): ActivePlugin | undefined => {
File without changes
@@ -5,30 +5,17 @@
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
10
+ URISchema,
11
+ FrontMatterTagsSchema,
12
+ FrontMatterTOCHeadingLevels,
12
13
  validateFrontMatter,
13
14
  } from '@docusaurus/utils-validation';
14
-
15
- export type DocFrontMatter = {
16
- id?: string;
17
- title?: string;
18
- hide_title?: boolean;
19
- hide_table_of_contents?: boolean;
20
- keywords?: string[];
21
- image?: string;
22
- description?: string;
23
- slug?: string;
24
- sidebar_label?: string;
25
- sidebar_position?: number;
26
- custom_edit_url?: string | null;
27
- parse_number_prefixes?: boolean;
28
- };
15
+ import type {DocFrontMatter} from './types';
29
16
 
30
17
  // NOTE: we don't add any default value on purpose here
31
- // 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
32
19
  // While the user did not provide those values explicitly
33
20
  // We use default values in code instead
34
21
  const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
@@ -37,13 +24,21 @@ const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
37
24
  hide_title: Joi.boolean(),
38
25
  hide_table_of_contents: Joi.boolean(),
39
26
  keywords: Joi.array().items(Joi.string().required()),
40
- image: Joi.string().uri({allowRelative: false}),
27
+ image: URISchema,
41
28
  description: Joi.string().allow(''), // see https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
42
29
  slug: Joi.string(),
43
30
  sidebar_label: Joi.string(),
44
- sidebar_position: Joi.number().min(0),
45
- custom_edit_url: Joi.string().uri({allowRelative: true}).allow('', null),
31
+ sidebar_position: Joi.number(),
32
+ sidebar_class_name: Joi.string(),
33
+ sidebar_custom_props: Joi.object().unknown(),
34
+ displayed_sidebar: Joi.string().allow(null),
35
+ tags: FrontMatterTagsSchema,
36
+ pagination_label: Joi.string(),
37
+ custom_edit_url: URISchema.allow('', null),
46
38
  parse_number_prefixes: Joi.boolean(),
39
+ pagination_next: Joi.string().allow(null),
40
+ pagination_prev: Joi.string().allow(null),
41
+ ...FrontMatterTOCHeadingLevels,
47
42
  }).unknown();
48
43
 
49
44
  export function validateDocFrontMatter(