@docusaurus/plugin-content-docs 2.0.0-beta.15a2b59f9 → 2.0.0-beta.17

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 (213) hide show
  1. package/lib/categoryGeneratedIndex.d.ts +12 -0
  2. package/lib/categoryGeneratedIndex.js +38 -0
  3. package/lib/cli.d.ts +2 -2
  4. package/lib/cli.js +27 -44
  5. package/lib/client/docsClientUtils.d.ts +3 -25
  6. package/lib/client/docsClientUtils.js +25 -24
  7. package/lib/{theme/hooks/useDocs.d.ts → client/index.d.ts} +1 -2
  8. package/lib/{theme/hooks/useDocs.js → client/index.js} +26 -26
  9. package/lib/docFrontMatter.d.ts +1 -1
  10. package/lib/docFrontMatter.js +9 -3
  11. package/lib/docs.d.ts +39 -3
  12. package/lib/docs.js +157 -53
  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 +110 -144
  17. package/lib/lastUpdate.js +15 -28
  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 +2 -2
  22. package/lib/numberPrefix.d.ts +1 -1
  23. package/lib/numberPrefix.js +9 -9
  24. package/lib/options.d.ts +3 -3
  25. package/lib/options.js +50 -10
  26. package/lib/props.d.ts +7 -2
  27. package/lib/props.js +66 -11
  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 +193 -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 +70 -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 +259 -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 +28 -17
  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 +91 -49
  54. package/lib/types.d.ts +40 -126
  55. package/lib/versions.d.ts +29 -4
  56. package/lib/versions.js +92 -87
  57. package/package.json +30 -27
  58. package/src/categoryGeneratedIndex.ts +59 -0
  59. package/src/cli.ts +34 -54
  60. package/src/client/docsClientUtils.ts +32 -57
  61. package/src/{theme/hooks/useDocs.ts → client/index.ts} +11 -10
  62. package/{types.d.ts → src/deps.d.ts} +0 -0
  63. package/src/docFrontMatter.ts +12 -5
  64. package/src/docs.ts +213 -47
  65. package/src/globalData.ts +53 -2
  66. package/src/index.ts +151 -197
  67. package/src/lastUpdate.ts +14 -37
  68. package/src/markdown/index.ts +9 -13
  69. package/src/markdown/linkify.ts +1 -1
  70. package/src/numberPrefix.ts +11 -8
  71. package/src/options.ts +59 -15
  72. package/src/plugin-content-docs.d.ts +249 -54
  73. package/src/props.ts +97 -18
  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 +269 -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 +39 -21
  86. package/src/tags.ts +19 -0
  87. package/src/translations.ts +121 -62
  88. package/src/types.ts +46 -183
  89. package/src/versions.ts +136 -102
  90. package/lib/.tsbuildinfo +0 -1
  91. package/lib/sidebarItemsGenerator.js +0 -211
  92. package/lib/sidebars.d.ts +0 -43
  93. package/lib/sidebars.js +0 -320
  94. package/src/__tests__/__fixtures__/bad-id-site/docs/invalid-id.md +0 -5
  95. package/src/__tests__/__fixtures__/bad-slug-on-doc-home-site/docs/docWithSlug.md +0 -5
  96. package/src/__tests__/__fixtures__/empty-site/docusaurus.config.js +0 -16
  97. package/src/__tests__/__fixtures__/empty-site/sidebars.json +0 -1
  98. package/src/__tests__/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -34
  99. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -11
  100. package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -11
  101. package/src/__tests__/__fixtures__/sidebars/sidebars-category.js +0 -44
  102. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -20
  103. package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed.json +0 -21
  104. package/src/__tests__/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -10
  105. package/src/__tests__/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -20
  106. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -11
  107. package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -11
  108. package/src/__tests__/__fixtures__/sidebars/sidebars-link.json +0 -11
  109. package/src/__tests__/__fixtures__/sidebars/sidebars-unknown-type.json +0 -14
  110. package/src/__tests__/__fixtures__/sidebars/sidebars-wrong-field.json +0 -20
  111. package/src/__tests__/__fixtures__/sidebars/sidebars.json +0 -20
  112. package/src/__tests__/__fixtures__/simple-site/docs/foo/bar.md +0 -69
  113. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +0 -70
  114. package/src/__tests__/__fixtures__/simple-site/docs/headingAsTitle.md +0 -1
  115. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +0 -53
  116. package/src/__tests__/__fixtures__/simple-site/docs/ipsum.md +0 -5
  117. package/src/__tests__/__fixtures__/simple-site/docs/lorem.md +0 -6
  118. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +0 -5
  119. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +0 -5
  120. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +0 -5
  121. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +0 -5
  122. package/src/__tests__/__fixtures__/simple-site/docs/slugs/absoluteSlug.md +0 -5
  123. package/src/__tests__/__fixtures__/simple-site/docs/slugs/relativeSlug.md +0 -5
  124. package/src/__tests__/__fixtures__/simple-site/docs/slugs/resolvedSlug.md +0 -5
  125. package/src/__tests__/__fixtures__/simple-site/docs/slugs/tryToEscapeSlug.md +0 -5
  126. package/src/__tests__/__fixtures__/simple-site/docusaurus.config.js +0 -14
  127. package/src/__tests__/__fixtures__/simple-site/sidebars.json +0 -23
  128. package/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json +0 -7
  129. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/0-getting-started.md +0 -3
  130. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/1-installation.md +0 -3
  131. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/00_api-overview.md +0 -3
  132. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/0 --- Client API.md +0 -1
  133. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/1 --- Server API.md +0 -1
  134. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/0. Plugin API.md +0 -1
  135. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/1. Theme API.md +0 -1
  136. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/_category_.yml +0 -1
  137. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/03_api-end.md +0 -3
  138. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/_category_.json +0 -3
  139. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/0-guide2.5.md +0 -8
  140. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/02-guide2.md +0 -7
  141. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/_category_.json +0 -3
  142. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/a-guide4.md +0 -7
  143. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/b-guide5.md +0 -7
  144. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/guide3.md +0 -8
  145. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/z-guide1.md +0 -8
  146. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docusaurus.config.js +0 -14
  147. package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars.js +0 -23
  148. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +0 -7
  149. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-2.md +0 -8
  150. package/src/__tests__/__fixtures__/site-with-doc-label/sidebars.json +0 -14
  151. package/src/__tests__/__fixtures__/versioned-site/community/team.md +0 -1
  152. package/src/__tests__/__fixtures__/versioned-site/community_sidebars.json +0 -3
  153. package/src/__tests__/__fixtures__/versioned-site/community_versioned_docs/version-1.0.0/team.md +0 -1
  154. package/src/__tests__/__fixtures__/versioned-site/community_versioned_sidebars/version-1.0.0-sidebars.json +0 -3
  155. package/src/__tests__/__fixtures__/versioned-site/community_versions.json +0 -1
  156. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +0 -4
  157. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +0 -1
  158. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/absoluteSlug.md +0 -5
  159. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/relativeSlug.md +0 -5
  160. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/resolvedSlug.md +0 -5
  161. package/src/__tests__/__fixtures__/versioned-site/docs/slugs/tryToEscapeSlug.md +0 -5
  162. package/src/__tests__/__fixtures__/versioned-site/docusaurus.config.js +0 -18
  163. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  164. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md +0 -5
  165. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
  166. package/src/__tests__/__fixtures__/versioned-site/sidebars.json +0 -10
  167. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/bar.md +0 -4
  168. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/baz.md +0 -1
  169. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +0 -1
  170. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/foo/bar.md +0 -1
  171. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +0 -1
  172. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md +0 -5
  173. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootRelativeSlug.md +0 -5
  174. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootResolvedSlug.md +0 -5
  175. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md +0 -5
  176. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md +0 -5
  177. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/relativeSlug.md +0 -5
  178. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md +0 -5
  179. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md +0 -5
  180. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
  181. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +0 -10
  182. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-withSlugs-sidebars.json +0 -5
  183. package/src/__tests__/__fixtures__/versioned-site/versions.json +0 -5
  184. package/src/__tests__/__snapshots__/cli.test.ts.snap +0 -90
  185. package/src/__tests__/__snapshots__/index.test.ts.snap +0 -1916
  186. package/src/__tests__/__snapshots__/sidebars.test.ts.snap +0 -218
  187. package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -487
  188. package/src/__tests__/cli.test.ts +0 -333
  189. package/src/__tests__/docFrontMatter.test.ts +0 -244
  190. package/src/__tests__/docs.test.ts +0 -878
  191. package/src/__tests__/index.test.ts +0 -1871
  192. package/src/__tests__/lastUpdate.test.ts +0 -69
  193. package/src/__tests__/numberPrefix.test.ts +0 -199
  194. package/src/__tests__/options.test.ts +0 -231
  195. package/src/__tests__/sidebarItemsGenerator.test.ts +0 -336
  196. package/src/__tests__/sidebars.test.ts +0 -639
  197. package/src/__tests__/slug.test.ts +0 -109
  198. package/src/__tests__/translations.test.ts +0 -159
  199. package/src/__tests__/versions.test.ts +0 -741
  200. package/src/client/__tests__/docsClientUtils.test.ts +0 -371
  201. package/src/markdown/__tests__/__fixtures__/docs/doc-localized.md +0 -1
  202. package/src/markdown/__tests__/__fixtures__/docs/doc1.md +0 -13
  203. package/src/markdown/__tests__/__fixtures__/docs/doc2.md +0 -12
  204. package/src/markdown/__tests__/__fixtures__/docs/doc4.md +0 -19
  205. package/src/markdown/__tests__/__fixtures__/docs/doc5.md +0 -6
  206. package/src/markdown/__tests__/__fixtures__/docs/subdir/doc3.md +0 -3
  207. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/doc2.md +0 -7
  208. package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/subdir/doc1.md +0 -3
  209. package/src/markdown/__tests__/__snapshots__/linkify.test.ts.snap +0 -82
  210. package/src/markdown/__tests__/linkify.test.ts +0 -190
  211. package/src/sidebarItemsGenerator.ts +0 -307
  212. package/src/sidebars.ts +0 -522
  213. package/tsconfig.json +0 -9
@@ -1,190 +0,0 @@
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 fs from 'fs-extra';
9
- import path from 'path';
10
- import {linkify} from '../linkify';
11
- import {
12
- DocsMarkdownOption,
13
- SourceToPermalink,
14
- VersionMetadata,
15
- BrokenMarkdownLink,
16
- } from '../../types';
17
- import {VERSIONED_DOCS_DIR, CURRENT_VERSION_NAME} from '../../constants';
18
-
19
- function createFakeVersion({
20
- versionName,
21
- contentPath,
22
- contentPathLocalized,
23
- }: {
24
- versionName: string;
25
- contentPath: string;
26
- contentPathLocalized: string;
27
- }): VersionMetadata {
28
- return {
29
- versionName,
30
- versionLabel: 'Any',
31
- versionPath: 'any',
32
- contentPath,
33
- contentPathLocalized,
34
- sidebarFilePath: 'any',
35
- routePriority: undefined,
36
- isLast: false,
37
- };
38
- }
39
-
40
- const siteDir = path.join(__dirname, '__fixtures__');
41
-
42
- const versionCurrent = createFakeVersion({
43
- versionName: CURRENT_VERSION_NAME,
44
- contentPath: path.join(siteDir, 'docs'),
45
- contentPathLocalized: path.join(
46
- siteDir,
47
- 'i18n',
48
- 'fr',
49
- 'docusaurus-plugin-content-docs',
50
- CURRENT_VERSION_NAME,
51
- ),
52
- });
53
-
54
- const version100 = createFakeVersion({
55
- versionName: '1.0.0',
56
- contentPath: path.join(siteDir, VERSIONED_DOCS_DIR, 'version-1.0.0'),
57
- contentPathLocalized: path.join(
58
- siteDir,
59
- 'i18n',
60
- 'fr',
61
- 'docusaurus-plugin-content-docs',
62
- 'version-1.0.0',
63
- ),
64
- });
65
-
66
- const sourceToPermalink: SourceToPermalink = {
67
- '@site/docs/doc1.md': '/docs/doc1',
68
- '@site/docs/doc2.md': '/docs/doc2',
69
- '@site/docs/subdir/doc3.md': '/docs/subdir/doc3',
70
- '@site/docs/doc4.md': '/docs/doc4',
71
- '@site/versioned_docs/version-1.0.0/doc2.md': '/docs/1.0.0/doc2',
72
- '@site/versioned_docs/version-1.0.0/subdir/doc1.md':
73
- '/docs/1.0.0/subdir/doc1',
74
-
75
- '@site/i18n/fr/docusaurus-plugin-content-docs/current/doc-localized.md':
76
- '/fr/doc-localized',
77
- '@site/docs/doc-localized': '/doc-localized',
78
- };
79
-
80
- function createMarkdownOptions(
81
- options?: Partial<DocsMarkdownOption>,
82
- ): DocsMarkdownOption {
83
- return {
84
- sourceToPermalink,
85
- onBrokenMarkdownLink: () => {},
86
- versionsMetadata: [versionCurrent, version100],
87
- siteDir,
88
- ...options,
89
- };
90
- }
91
-
92
- const transform = (filepath: string, options?: Partial<DocsMarkdownOption>) => {
93
- const markdownOptions = createMarkdownOptions(options);
94
- const content = fs.readFileSync(filepath, 'utf-8');
95
- const transformedContent = linkify(content, filepath, markdownOptions);
96
- return [content, transformedContent];
97
- };
98
-
99
- test('transform nothing', () => {
100
- const doc1 = path.join(versionCurrent.contentPath, 'doc1.md');
101
- const [content, transformedContent] = transform(doc1);
102
- expect(transformedContent).toMatchSnapshot();
103
- expect(content).toEqual(transformedContent);
104
- });
105
-
106
- test('transform to correct links', () => {
107
- const doc2 = path.join(versionCurrent.contentPath, 'doc2.md');
108
- const [content, transformedContent] = transform(doc2);
109
- expect(transformedContent).toMatchSnapshot();
110
- expect(transformedContent).toContain('](/docs/doc1');
111
- expect(transformedContent).toContain('](/docs/doc2');
112
- expect(transformedContent).toContain('](/docs/subdir/doc3');
113
- expect(transformedContent).toContain('](/fr/doc-localized');
114
- expect(transformedContent).not.toContain('](doc1.md)');
115
- expect(transformedContent).not.toContain('](./doc2.md)');
116
- expect(transformedContent).not.toContain('](subdir/doc3.md)');
117
- expect(transformedContent).not.toContain('](/doc-localized');
118
- expect(content).not.toEqual(transformedContent);
119
- });
120
-
121
- test('transform relative links', () => {
122
- const doc3 = path.join(versionCurrent.contentPath, 'subdir', 'doc3.md');
123
-
124
- const [content, transformedContent] = transform(doc3);
125
- expect(transformedContent).toMatchSnapshot();
126
- expect(transformedContent).toContain('](/docs/doc2');
127
- expect(transformedContent).not.toContain('](../doc2.md)');
128
- expect(content).not.toEqual(transformedContent);
129
- });
130
-
131
- test('transforms reference links', () => {
132
- const doc4 = path.join(versionCurrent.contentPath, 'doc4.md');
133
- const [content, transformedContent] = transform(doc4);
134
- expect(transformedContent).toMatchSnapshot();
135
- expect(transformedContent).toContain('[doc1]: /docs/doc1');
136
- expect(transformedContent).toContain('[doc2]: /docs/doc2');
137
- expect(transformedContent).not.toContain('[doc1]: doc1.md');
138
- expect(transformedContent).not.toContain('[doc2]: ./doc2.md');
139
- expect(content).not.toEqual(transformedContent);
140
- });
141
-
142
- test('report broken markdown links', () => {
143
- const doc5 = path.join(versionCurrent.contentPath, 'doc5.md');
144
- const onBrokenMarkdownLink = jest.fn();
145
- const [content, transformedContent] = transform(doc5, {
146
- onBrokenMarkdownLink,
147
- });
148
- expect(transformedContent).toEqual(content);
149
- expect(onBrokenMarkdownLink).toHaveBeenCalledTimes(4);
150
- expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(1, {
151
- filePath: doc5,
152
- link: 'docNotExist1.md',
153
- contentPaths: versionCurrent,
154
- } as BrokenMarkdownLink);
155
- expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(2, {
156
- filePath: doc5,
157
- link: './docNotExist2.mdx',
158
- contentPaths: versionCurrent,
159
- } as BrokenMarkdownLink);
160
- expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(3, {
161
- filePath: doc5,
162
- link: '../docNotExist3.mdx',
163
- contentPaths: versionCurrent,
164
- } as BrokenMarkdownLink);
165
- expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(4, {
166
- filePath: doc5,
167
- link: './subdir/docNotExist4.md',
168
- contentPaths: versionCurrent,
169
- } as BrokenMarkdownLink);
170
- });
171
-
172
- test('transforms absolute links in versioned docs', () => {
173
- const doc2 = path.join(version100.contentPath, 'doc2.md');
174
- const [content, transformedContent] = transform(doc2);
175
- expect(transformedContent).toMatchSnapshot();
176
- expect(transformedContent).toContain('](/docs/1.0.0/subdir/doc1');
177
- expect(transformedContent).toContain('](/docs/1.0.0/doc2#existing-docs');
178
- expect(transformedContent).not.toContain('](subdir/doc1.md)');
179
- expect(transformedContent).not.toContain('](doc2.md#existing-docs)');
180
- expect(content).not.toEqual(transformedContent);
181
- });
182
-
183
- test('transforms relative links in versioned docs', () => {
184
- const doc1 = path.join(version100.contentPath, 'subdir', 'doc1.md');
185
- const [content, transformedContent] = transform(doc1);
186
- expect(transformedContent).toMatchSnapshot();
187
- expect(transformedContent).toContain('](/docs/1.0.0/doc2');
188
- expect(transformedContent).not.toContain('](../doc2.md)');
189
- expect(content).not.toEqual(transformedContent);
190
- });
@@ -1,307 +0,0 @@
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 {
9
- SidebarItem,
10
- SidebarItemDoc,
11
- SidebarItemCategory,
12
- SidebarItemsGenerator,
13
- SidebarItemsGeneratorDoc,
14
- } from './types';
15
- import {sortBy, take, last, orderBy} from 'lodash';
16
- import {addTrailingSlash, posixPath} from '@docusaurus/utils';
17
- import {Joi} from '@docusaurus/utils-validation';
18
- import chalk from 'chalk';
19
- import path from 'path';
20
- import fs from 'fs-extra';
21
- import Yaml from 'js-yaml';
22
- import {DefaultCategoryCollapsedValue} from './sidebars';
23
-
24
- const BreadcrumbSeparator = '/';
25
-
26
- export const CategoryMetadataFilenameBase = '_category_';
27
- export const CategoryMetadataFilenamePattern = '_category_.{json,yml,yaml}';
28
-
29
- export type CategoryMetadatasFile = {
30
- label?: string;
31
- position?: number;
32
- collapsed?: boolean;
33
-
34
- // TODO should we allow "items" here? how would this work? would an "autogenerated" type be allowed?
35
- // This mkdocs plugin do something like that: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin/
36
- // cf comment: https://github.com/facebook/docusaurus/issues/3464#issuecomment-784765199
37
- };
38
-
39
- type WithPosition = {position?: number};
40
- type SidebarItemWithPosition = SidebarItem & WithPosition;
41
-
42
- const CategoryMetadatasFileSchema = Joi.object<CategoryMetadatasFile>({
43
- label: Joi.string(),
44
- position: Joi.number(),
45
- collapsed: Joi.boolean(),
46
- });
47
-
48
- // TODO I now believe we should read all the category metadata files ahead of time: we may need this metadata to customize docs metadata
49
- // Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
50
- // TODO later if there is `CategoryFolder/index.md`, we may want to read the metadata as yaml on it
51
- // see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
52
- async function readCategoryMetadatasFile(
53
- categoryDirPath: string,
54
- ): Promise<CategoryMetadatasFile | null> {
55
- function validateCategoryMetadataFile(
56
- content: unknown,
57
- ): CategoryMetadatasFile {
58
- return Joi.attempt(content, CategoryMetadatasFileSchema);
59
- }
60
-
61
- async function tryReadFile(
62
- fileNameWithExtension: string,
63
- parse: (content: string) => unknown,
64
- ): Promise<CategoryMetadatasFile | null> {
65
- // Simpler to use only posix paths for mocking file metadatas in tests
66
- const filePath = posixPath(
67
- path.join(categoryDirPath, fileNameWithExtension),
68
- );
69
- if (await fs.pathExists(filePath)) {
70
- const contentString = await fs.readFile(filePath, {encoding: 'utf8'});
71
- const unsafeContent: unknown = parse(contentString);
72
- try {
73
- return validateCategoryMetadataFile(unsafeContent);
74
- } catch (e) {
75
- console.error(
76
- chalk.red(
77
- `The docs sidebar category metadata file looks invalid!\nPath: ${filePath}`,
78
- ),
79
- );
80
- throw e;
81
- }
82
- }
83
- return null;
84
- }
85
-
86
- return (
87
- (await tryReadFile(`${CategoryMetadataFilenameBase}.json`, JSON.parse)) ??
88
- (await tryReadFile(`${CategoryMetadataFilenameBase}.yml`, Yaml.load)) ??
89
- // eslint-disable-next-line no-return-await
90
- (await tryReadFile(`${CategoryMetadataFilenameBase}.yaml`, Yaml.load))
91
- );
92
- }
93
-
94
- // [...parents, tail]
95
- function parseBreadcrumb(
96
- breadcrumb: string[],
97
- ): {parents: string[]; tail: string} {
98
- return {
99
- parents: take(breadcrumb, breadcrumb.length - 1),
100
- tail: last(breadcrumb)!,
101
- };
102
- }
103
-
104
- // Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
105
- export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async function defaultSidebarItemsGenerator({
106
- item,
107
- docs: allDocs,
108
- version,
109
- numberPrefixParser,
110
- }): Promise<SidebarItem[]> {
111
- // Doc at the root of the autogenerated sidebar dir
112
- function isRootDoc(doc: SidebarItemsGeneratorDoc) {
113
- return doc.sourceDirName === item.dirName;
114
- }
115
-
116
- // Doc inside a subfolder of the autogenerated sidebar dir
117
- function isCategoryDoc(doc: SidebarItemsGeneratorDoc) {
118
- if (isRootDoc(doc)) {
119
- return false;
120
- }
121
-
122
- return (
123
- // autogen dir is . and doc is in subfolder
124
- item.dirName === '.' ||
125
- // autogen dir is not . and doc is in subfolder
126
- // "api/myDoc" startsWith "api/" (note "api2/myDoc" is not included)
127
- doc.sourceDirName.startsWith(addTrailingSlash(item.dirName))
128
- );
129
- }
130
-
131
- function isInAutogeneratedDir(doc: SidebarItemsGeneratorDoc) {
132
- return isRootDoc(doc) || isCategoryDoc(doc);
133
- }
134
-
135
- // autogenDir=a/b and docDir=a/b/c/d => returns c/d
136
- // autogenDir=a/b and docDir=a/b => returns .
137
- function getDocDirRelativeToAutogenDir(
138
- doc: SidebarItemsGeneratorDoc,
139
- ): string {
140
- if (!isInAutogeneratedDir(doc)) {
141
- throw new Error(
142
- 'getDocDirRelativeToAutogenDir() can only be called for subdocs of the sidebar autogen dir.',
143
- );
144
- }
145
- // Is there a node API to compare 2 relative paths more easily?
146
- // path.relative() does not give good results
147
- if (item.dirName === '.') {
148
- return doc.sourceDirName;
149
- } else if (item.dirName === doc.sourceDirName) {
150
- return '.';
151
- } else {
152
- return doc.sourceDirName.replace(addTrailingSlash(item.dirName), '');
153
- }
154
- }
155
-
156
- // Get only docs in the autogen dir
157
- // Sort by folder+filename at once
158
- const docs = sortBy(allDocs.filter(isInAutogeneratedDir), (d) => d.source);
159
-
160
- if (docs.length === 0) {
161
- console.warn(
162
- chalk.yellow(
163
- `No docs found in dir ${item.dirName}: can't auto-generate a sidebar.`,
164
- ),
165
- );
166
- }
167
-
168
- function createDocSidebarItem(
169
- doc: SidebarItemsGeneratorDoc,
170
- ): SidebarItemDoc & WithPosition {
171
- return {
172
- type: 'doc',
173
- id: doc.id,
174
- ...(doc.frontMatter.sidebar_label && {
175
- label: doc.frontMatter.sidebar_label,
176
- }),
177
- ...(typeof doc.sidebarPosition !== 'undefined' && {
178
- position: doc.sidebarPosition,
179
- }),
180
- };
181
- }
182
-
183
- async function createCategorySidebarItem({
184
- breadcrumb,
185
- }: {
186
- breadcrumb: string[];
187
- }): Promise<SidebarItemCategory & WithPosition> {
188
- const categoryDirPath = path.join(
189
- version.contentPath,
190
- item.dirName, // fix https://github.com/facebook/docusaurus/issues/4638
191
- breadcrumb.join(BreadcrumbSeparator),
192
- );
193
-
194
- const categoryMetadatas = await readCategoryMetadatasFile(categoryDirPath);
195
-
196
- const {tail} = parseBreadcrumb(breadcrumb);
197
-
198
- const {filename, numberPrefix} = numberPrefixParser(tail);
199
-
200
- const position = categoryMetadatas?.position ?? numberPrefix;
201
-
202
- return {
203
- type: 'category',
204
- label: categoryMetadatas?.label ?? filename,
205
- items: [],
206
- collapsed: categoryMetadatas?.collapsed ?? DefaultCategoryCollapsedValue,
207
- ...(typeof position !== 'undefined' && {position}),
208
- };
209
- }
210
-
211
- // Not sure how to simplify this algorithm :/
212
- async function autogenerateSidebarItems(): Promise<
213
- SidebarItemWithPosition[]
214
- > {
215
- const sidebarItems: SidebarItem[] = []; // mutable result
216
-
217
- const categoriesByBreadcrumb: Record<string, SidebarItemCategory> = {}; // mutable cache of categories already created
218
-
219
- async function getOrCreateCategoriesForBreadcrumb(
220
- breadcrumb: string[],
221
- ): Promise<SidebarItemCategory | null> {
222
- if (breadcrumb.length === 0) {
223
- return null;
224
- }
225
- const {parents} = parseBreadcrumb(breadcrumb);
226
- const parentCategory = await getOrCreateCategoriesForBreadcrumb(parents);
227
- const existingCategory =
228
- categoriesByBreadcrumb[breadcrumb.join(BreadcrumbSeparator)];
229
-
230
- if (existingCategory) {
231
- return existingCategory;
232
- } else {
233
- const newCategory = await createCategorySidebarItem({
234
- breadcrumb,
235
- });
236
- if (parentCategory) {
237
- parentCategory.items.push(newCategory);
238
- } else {
239
- sidebarItems.push(newCategory);
240
- }
241
- categoriesByBreadcrumb[
242
- breadcrumb.join(BreadcrumbSeparator)
243
- ] = newCategory;
244
- return newCategory;
245
- }
246
- }
247
-
248
- // Get the category breadcrumb of a doc (relative to the dir of the autogenerated sidebar item)
249
- function getRelativeBreadcrumb(doc: SidebarItemsGeneratorDoc): string[] {
250
- const relativeDirPath = getDocDirRelativeToAutogenDir(doc);
251
- if (relativeDirPath === '.') {
252
- return [];
253
- } else {
254
- return relativeDirPath.split(BreadcrumbSeparator);
255
- }
256
- }
257
-
258
- async function handleDocItem(doc: SidebarItemsGeneratorDoc): Promise<void> {
259
- const breadcrumb = getRelativeBreadcrumb(doc);
260
- const category = await getOrCreateCategoriesForBreadcrumb(breadcrumb);
261
-
262
- const docSidebarItem = createDocSidebarItem(doc);
263
- if (category) {
264
- category.items.push(docSidebarItem);
265
- } else {
266
- sidebarItems.push(docSidebarItem);
267
- }
268
- }
269
-
270
- // async process made sequential on purpose! order matters
271
- for (const doc of docs) {
272
- // eslint-disable-next-line no-await-in-loop
273
- await handleDocItem(doc);
274
- }
275
-
276
- return sidebarItems;
277
- }
278
-
279
- const sidebarItems = await autogenerateSidebarItems();
280
-
281
- return sortSidebarItems(sidebarItems);
282
- };
283
-
284
- // Recursively sort the categories/docs + remove the "position" attribute from final output
285
- // Note: the "position" is only used to sort "inside" a sidebar slice
286
- // It is not used to sort across multiple consecutive sidebar slices (ie a whole Category composed of multiple autogenerated items)
287
- function sortSidebarItems(
288
- sidebarItems: SidebarItemWithPosition[],
289
- ): SidebarItem[] {
290
- const processedSidebarItems = sidebarItems.map((item) => {
291
- if (item.type === 'category') {
292
- return {
293
- ...item,
294
- items: sortSidebarItems(item.items),
295
- };
296
- }
297
- return item;
298
- });
299
-
300
- const sortedSidebarItems = orderBy(
301
- processedSidebarItems,
302
- (item) => item.position,
303
- ['asc'],
304
- );
305
-
306
- return sortedSidebarItems.map(({position: _removed, ...item}) => item);
307
- }