@docusaurus/plugin-content-docs 2.0.0-beta.12faed89d → 2.0.0-beta.13

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 (138) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/categoryGeneratedIndex.d.ts +12 -0
  3. package/lib/categoryGeneratedIndex.js +37 -0
  4. package/lib/cli.d.ts +2 -2
  5. package/lib/cli.js +12 -34
  6. package/lib/client/docsClientUtils.d.ts +0 -3
  7. package/lib/client/docsClientUtils.js +19 -22
  8. package/lib/docFrontMatter.d.ts +1 -1
  9. package/lib/docFrontMatter.js +7 -3
  10. package/lib/docs.d.ts +25 -3
  11. package/lib/docs.js +125 -41
  12. package/lib/globalData.d.ts +1 -1
  13. package/lib/index.d.ts +1 -1
  14. package/lib/index.js +100 -131
  15. package/lib/lastUpdate.js +8 -9
  16. package/lib/markdown/index.d.ts +3 -6
  17. package/lib/markdown/index.js +3 -3
  18. package/lib/markdown/linkify.js +2 -2
  19. package/lib/numberPrefix.d.ts +1 -1
  20. package/lib/options.d.ts +3 -3
  21. package/lib/options.js +48 -11
  22. package/lib/props.d.ts +7 -2
  23. package/lib/props.js +60 -8
  24. package/lib/routes.d.ts +27 -0
  25. package/lib/routes.js +105 -0
  26. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +5 -2
  27. package/lib/sidebars/generator.js +216 -0
  28. package/lib/sidebars/index.d.ts +15 -0
  29. package/lib/sidebars/index.js +73 -0
  30. package/lib/sidebars/normalization.d.ts +14 -0
  31. package/lib/sidebars/normalization.js +77 -0
  32. package/lib/sidebars/processor.d.ts +18 -0
  33. package/lib/sidebars/processor.js +85 -0
  34. package/lib/sidebars/types.d.ts +127 -0
  35. package/lib/sidebars/types.js +8 -0
  36. package/lib/sidebars/utils.d.ts +35 -0
  37. package/lib/sidebars/utils.js +228 -0
  38. package/lib/sidebars/validation.d.ts +10 -0
  39. package/lib/sidebars/validation.js +138 -0
  40. package/lib/slug.d.ts +4 -3
  41. package/lib/slug.js +27 -15
  42. package/lib/tags.d.ts +8 -0
  43. package/lib/tags.js +20 -0
  44. package/lib/theme/hooks/useDocs.js +21 -21
  45. package/lib/translations.d.ts +2 -2
  46. package/lib/translations.js +71 -29
  47. package/lib/types.d.ts +52 -63
  48. package/lib/versions.d.ts +3 -3
  49. package/lib/versions.js +41 -22
  50. package/package.json +20 -20
  51. package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
  52. package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
  53. package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
  54. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  55. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +2 -0
  56. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  57. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  58. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  59. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  60. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  61. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +1 -0
  62. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  63. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +3 -0
  64. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  65. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  66. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +3 -0
  67. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
  68. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
  69. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
  70. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +3 -0
  71. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
  72. package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -73
  73. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  74. package/src/__tests__/__snapshots__/index.test.ts.snap +745 -97
  75. package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -15
  76. package/src/__tests__/cli.test.ts +15 -11
  77. package/src/__tests__/docFrontMatter.test.ts +160 -45
  78. package/src/__tests__/docs.test.ts +311 -150
  79. package/src/__tests__/index.test.ts +108 -66
  80. package/src/__tests__/lastUpdate.test.ts +1 -1
  81. package/src/__tests__/options.test.ts +48 -3
  82. package/src/__tests__/props.test.ts +62 -0
  83. package/src/__tests__/slug.test.ts +127 -20
  84. package/src/__tests__/translations.test.ts +7 -1
  85. package/src/__tests__/versions.test.ts +73 -70
  86. package/src/categoryGeneratedIndex.ts +57 -0
  87. package/src/cli.ts +8 -41
  88. package/src/client/docsClientUtils.ts +14 -26
  89. package/{types.d.ts → src/deps.d.ts} +0 -0
  90. package/src/docFrontMatter.ts +9 -4
  91. package/src/docs.ts +158 -32
  92. package/src/globalData.ts +6 -1
  93. package/src/index.ts +125 -169
  94. package/src/lastUpdate.ts +10 -13
  95. package/src/markdown/index.ts +8 -12
  96. package/src/numberPrefix.ts +5 -3
  97. package/src/options.ts +59 -14
  98. package/src/plugin-content-docs.d.ts +173 -40
  99. package/src/props.ts +90 -15
  100. package/src/routes.ts +173 -0
  101. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  102. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  103. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  104. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  105. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  106. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  107. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  108. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  109. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  110. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  111. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  112. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  113. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  114. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  115. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +36 -6
  116. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +143 -18
  117. package/src/sidebars/__tests__/index.test.ts +204 -0
  118. package/src/sidebars/__tests__/processor.test.ts +237 -0
  119. package/src/sidebars/__tests__/utils.test.ts +695 -0
  120. package/src/sidebars/__tests__/validation.test.ts +105 -0
  121. package/src/sidebars/generator.ts +310 -0
  122. package/src/sidebars/index.ts +94 -0
  123. package/src/sidebars/normalization.ts +112 -0
  124. package/src/sidebars/processor.ts +154 -0
  125. package/src/sidebars/types.ts +211 -0
  126. package/src/sidebars/utils.ts +329 -0
  127. package/src/sidebars/validation.ts +168 -0
  128. package/src/slug.ts +32 -17
  129. package/src/tags.ts +19 -0
  130. package/src/translations.ts +103 -47
  131. package/src/types.ts +64 -107
  132. package/src/versions.ts +59 -25
  133. package/lib/sidebarItemsGenerator.js +0 -211
  134. package/lib/sidebars.d.ts +0 -43
  135. package/lib/sidebars.js +0 -320
  136. package/src/__tests__/sidebars.test.ts +0 -639
  137. package/src/sidebarItemsGenerator.ts +0 -307
  138. package/src/sidebars.ts +0 -522
@@ -5,51 +5,84 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- /* eslint-disable camelcase */
8
+ declare module '@docusaurus/plugin-content-docs' {
9
+ export type Options = Partial<import('./types').PluginOptions>;
10
+ export type SidebarsConfig = import('./sidebars/types').SidebarsConfig;
11
+ export type VersionBanner = import('./types').VersionBanner;
12
+ type GlobalDataVersion = import('./types').GlobalVersion;
13
+ type GlobalDataDoc = import('./types').GlobalDoc;
14
+ type VersionTag = import('./types').VersionTag;
9
15
 
10
- declare module '@docusaurus/plugin-content-docs-types' {
11
- import type {VersionBanner} from './types';
16
+ export type {GlobalDataVersion, GlobalDataDoc};
17
+
18
+ export type PropNavigationLink = {
19
+ readonly title: string;
20
+ readonly permalink: string;
21
+ };
22
+ export type PropNavigation = {
23
+ readonly previous?: PropNavigationLink;
24
+ readonly next?: PropNavigationLink;
25
+ };
26
+
27
+ export type PropVersionDoc = import('./sidebars/types').PropVersionDoc;
28
+ export type PropVersionDocs = import('./sidebars/types').PropVersionDocs;
12
29
 
13
30
  export type PropVersionMetadata = {
14
31
  pluginId: string;
15
32
  version: string;
16
33
  label: string;
17
- banner: VersionBanner;
34
+ banner: VersionBanner | null;
35
+ badge: boolean;
36
+ className: string;
18
37
  isLast: boolean;
19
38
  docsSidebars: PropSidebars;
39
+ docs: PropVersionDocs;
20
40
  };
21
41
 
22
- type PropsSidebarItemBase = {
23
- customProps?: Record<string, unknown>;
42
+ export type PropCategoryGeneratedIndex = {
43
+ title: string;
44
+ description?: string;
45
+ slug: string;
46
+ permalink: string;
47
+ navigation: PropNavigation;
24
48
  };
25
49
 
26
- export type PropSidebarItemLink = PropsSidebarItemBase & {
27
- type: 'link';
28
- href: string;
29
- label: string;
30
- };
50
+ export type PropSidebarItemLink =
51
+ import('./sidebars/types').PropSidebarItemLink;
52
+ export type PropSidebarItemCategory =
53
+ import('./sidebars/types').PropSidebarItemCategory;
54
+ export type PropSidebarItem = import('./sidebars/types').PropSidebarItem;
55
+ export type PropSidebar = import('./sidebars/types').PropSidebar;
56
+ export type PropSidebars = import('./sidebars/types').PropSidebars;
31
57
 
32
- export type PropSidebarItemCategory = PropsSidebarItemBase & {
33
- type: 'category';
34
- label: string;
35
- items: PropSidebarItem[];
36
- collapsed?: boolean;
58
+ export type PropTagDocListDoc = {
59
+ id: string;
60
+ title: string;
61
+ description: string;
62
+ permalink: string;
37
63
  };
38
-
39
- export type PropSidebarItem = PropSidebarItemLink | PropSidebarItemCategory;
40
-
41
- export type PropSidebars = {
42
- [sidebarId: string]: PropSidebarItem[];
64
+ export type PropTagDocList = {
65
+ allTagsPath: string;
66
+ name: string; // normalized name/label of the tag
67
+ permalink: string; // pathname of the tag
68
+ docs: PropTagDocListDoc[];
43
69
  };
44
70
 
45
- export type {
46
- GlobalVersion as GlobalDataVersion,
47
- GlobalDoc as GlobalDataDoc,
48
- } from './types';
71
+ export type PropTagsListPage = {
72
+ tags: {
73
+ name: string;
74
+ permalink: string;
75
+ count: number;
76
+ }[];
77
+ };
49
78
  }
50
79
 
51
80
  declare module '@theme/DocItem' {
52
81
  import type {TOCItem} from '@docusaurus/types';
82
+ import type {
83
+ PropNavigationLink,
84
+ PropVersionMetadata,
85
+ } from '@docusaurus/plugin-content-docs';
53
86
 
54
87
  export type DocumentRoute = {
55
88
  readonly component: () => JSX.Element;
@@ -65,6 +98,8 @@ declare module '@theme/DocItem' {
65
98
  readonly keywords?: readonly string[];
66
99
  readonly hide_title?: boolean;
67
100
  readonly hide_table_of_contents?: boolean;
101
+ readonly toc_min_heading_level?: number;
102
+ readonly toc_max_heading_level?: number;
68
103
  };
69
104
 
70
105
  export type Metadata = {
@@ -76,11 +111,15 @@ declare module '@theme/DocItem' {
76
111
  readonly formattedLastUpdatedAt?: string;
77
112
  readonly lastUpdatedBy?: string;
78
113
  readonly version?: string;
79
- readonly previous?: {readonly permalink: string; readonly title: string};
80
- readonly next?: {readonly permalink: string; readonly title: string};
114
+ readonly previous?: PropNavigationLink;
115
+ readonly next?: PropNavigationLink;
116
+ readonly tags: readonly {
117
+ readonly label: string;
118
+ readonly permalink: string;
119
+ }[];
81
120
  };
82
121
 
83
- export type Props = {
122
+ export interface Props {
84
123
  readonly route: DocumentRoute;
85
124
  readonly versionMetadata: PropVersionMetadata;
86
125
  readonly content: {
@@ -90,28 +129,87 @@ declare module '@theme/DocItem' {
90
129
  readonly contentTitle: string | undefined;
91
130
  (): JSX.Element;
92
131
  };
93
- };
132
+ }
94
133
 
95
134
  const DocItem: (props: Props) => JSX.Element;
96
135
  export default DocItem;
97
136
  }
98
137
 
138
+ declare module '@theme/DocCard' {
139
+ import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
140
+
141
+ export interface Props {
142
+ readonly item: PropSidebarItem;
143
+ }
144
+
145
+ export default function DocCard(props: Props): JSX.Element;
146
+ }
147
+
148
+ declare module '@theme/DocCardList' {
149
+ import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
150
+
151
+ export interface Props {
152
+ readonly items: PropSidebarItem[];
153
+ }
154
+
155
+ export default function DocCardList(props: Props): JSX.Element;
156
+ }
157
+
158
+ declare module '@theme/DocCategoryGeneratedIndexPage' {
159
+ import type {PropCategoryGeneratedIndex} from '@docusaurus/plugin-content-docs';
160
+
161
+ export interface Props {
162
+ readonly categoryGeneratedIndex: PropCategoryGeneratedIndex;
163
+ }
164
+
165
+ export default function DocCategoryGeneratedIndexPage(
166
+ props: Props,
167
+ ): JSX.Element;
168
+ }
169
+
170
+ declare module '@theme/DocItemFooter' {
171
+ import type {Props} from '@theme/DocItem';
172
+
173
+ export default function DocItemFooter(props: Props): JSX.Element;
174
+ }
175
+
176
+ declare module '@theme/DocTagsListPage' {
177
+ import type {PropTagsListPage} from '@docusaurus/plugin-content-docs';
178
+
179
+ export interface Props extends PropTagsListPage {}
180
+ export default function DocTagsListPage(props: Props): JSX.Element;
181
+ }
182
+
183
+ declare module '@theme/DocTagDocListPage' {
184
+ import type {PropTagDocList} from '@docusaurus/plugin-content-docs';
185
+
186
+ export interface Props {
187
+ readonly tag: PropTagDocList;
188
+ }
189
+ export default function DocTagDocListPage(props: Props): JSX.Element;
190
+ }
191
+
99
192
  declare module '@theme/DocVersionBanner' {
100
- import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
193
+ export interface Props {
194
+ readonly className?: string;
195
+ }
101
196
 
102
- export type Props = {
103
- readonly versionMetadata: PropVersionMetadata;
104
- };
197
+ export default function DocVersionBanner(props: Props): JSX.Element;
198
+ }
105
199
 
106
- const DocVersionBanner: (props: Props) => JSX.Element;
107
- export default DocVersionBanner;
200
+ declare module '@theme/DocVersionBadge' {
201
+ export interface Props {
202
+ readonly className?: string;
203
+ }
204
+
205
+ export default function DocVersionBadge(props: Props): JSX.Element;
108
206
  }
109
207
 
110
208
  declare module '@theme/DocPage' {
111
- import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types';
209
+ import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs';
112
210
  import type {DocumentRoute} from '@theme/DocItem';
113
211
 
114
- export type Props = {
212
+ export interface Props {
115
213
  readonly location: {readonly pathname: string};
116
214
  readonly versionMetadata: PropVersionMetadata;
117
215
  readonly route: {
@@ -119,20 +217,55 @@ declare module '@theme/DocPage' {
119
217
  readonly component: () => JSX.Element;
120
218
  readonly routes: DocumentRoute[];
121
219
  };
122
- };
220
+ }
123
221
 
124
222
  const DocPage: (props: Props) => JSX.Element;
125
223
  export default DocPage;
126
224
  }
127
225
 
128
226
  declare module '@theme/Seo' {
129
- export type Props = {
227
+ import type {ReactNode} from 'react';
228
+
229
+ export interface Props {
130
230
  readonly title?: string;
131
231
  readonly description?: string;
132
232
  readonly keywords?: readonly string[] | string;
133
233
  readonly image?: string;
134
- };
234
+ readonly children?: ReactNode;
235
+ }
135
236
 
136
237
  const Seo: (props: Props) => JSX.Element;
137
238
  export default Seo;
138
239
  }
240
+
241
+ declare module '@theme/hooks/useDocs' {
242
+ type GlobalPluginData = import('./types').GlobalPluginData;
243
+ type GlobalVersion = import('./types').GlobalVersion;
244
+ type ActivePlugin = import('./client/docsClientUtils').ActivePlugin;
245
+ type ActiveDocContext = import('./client/docsClientUtils').ActiveDocContext;
246
+ type DocVersionSuggestions =
247
+ import('./client/docsClientUtils').DocVersionSuggestions;
248
+ type GetActivePluginOptions =
249
+ import('./client/docsClientUtils').GetActivePluginOptions;
250
+
251
+ export type {GlobalPluginData, GlobalVersion};
252
+ export const useAllDocsData: () => Record<string, GlobalPluginData>;
253
+ export const useDocsData: (pluginId?: string) => GlobalPluginData;
254
+ export const useActivePlugin: (
255
+ options?: GetActivePluginOptions,
256
+ ) => ActivePlugin | undefined;
257
+ export const useActivePluginAndVersion: (
258
+ options?: GetActivePluginOptions,
259
+ ) =>
260
+ | {activePlugin: ActivePlugin; activeVersion: GlobalVersion | undefined}
261
+ | undefined;
262
+ export const useVersions: (pluginId?: string) => GlobalVersion[];
263
+ export const useLatestVersion: (pluginId?: string) => GlobalVersion;
264
+ export const useActiveVersion: (
265
+ pluginId?: string,
266
+ ) => GlobalVersion | undefined;
267
+ export const useActiveDocContext: (pluginId?: string) => ActiveDocContext;
268
+ export const useDocVersionSuggestions: (
269
+ pluginId?: string,
270
+ ) => DocVersionSuggestions;
271
+ }
package/src/props.ts CHANGED
@@ -5,26 +5,31 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {
9
- LoadedVersion,
8
+ import type {LoadedVersion, VersionTag, DocMetadata} from './types';
9
+ import type {
10
10
  SidebarItemDoc,
11
- SidebarItemLink,
12
11
  SidebarItem,
13
- } from './types';
14
- import {
12
+ SidebarItemCategory,
13
+ SidebarItemCategoryLink,
14
+ PropVersionDocs,
15
+ } from './sidebars/types';
16
+ import type {
15
17
  PropSidebars,
16
18
  PropVersionMetadata,
17
19
  PropSidebarItem,
18
- } from '@docusaurus/plugin-content-docs-types';
19
- import {keyBy, mapValues} from 'lodash';
20
+ PropSidebarItemCategory,
21
+ PropTagDocList,
22
+ PropTagDocListDoc,
23
+ PropSidebarItemLink,
24
+ } from '@docusaurus/plugin-content-docs';
25
+ import {compact, keyBy, mapValues} from 'lodash';
26
+ import {createDocsByIdIndex} from './docs';
20
27
 
21
28
  export function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars {
22
- const docsById = keyBy(loadedVersion.docs, (doc) => doc.id);
29
+ const docsById = createDocsByIdIndex(loadedVersion.docs);
23
30
 
24
- const convertDocLink = (item: SidebarItemDoc): SidebarItemLink => {
25
- const docId = item.id;
31
+ function getDocById(docId: string): DocMetadata {
26
32
  const docMetadata = docsById[docId];
27
-
28
33
  if (!docMetadata) {
29
34
  throw new Error(
30
35
  `Invalid sidebars file. The document with id "${docId}" was used in the sidebar, but no document with this id could be found.
@@ -32,25 +37,49 @@ Available document ids are:
32
37
  - ${Object.keys(docsById).sort().join('\n- ')}`,
33
38
  );
34
39
  }
40
+ return docMetadata;
41
+ }
35
42
 
43
+ const convertDocLink = (item: SidebarItemDoc): PropSidebarItemLink => {
44
+ const docMetadata = getDocById(item.id);
36
45
  const {
37
46
  title,
38
47
  permalink,
39
48
  frontMatter: {sidebar_label: sidebarLabel},
40
49
  } = docMetadata;
41
-
42
50
  return {
43
51
  type: 'link',
44
52
  label: sidebarLabel || item.label || title,
45
53
  href: permalink,
54
+ className: item.className,
46
55
  customProps: item.customProps,
56
+ docId: docMetadata.unversionedId,
47
57
  };
48
58
  };
49
59
 
50
- const normalizeItem = (item: SidebarItem): PropSidebarItem => {
60
+ function getCategoryLinkHref(
61
+ link: SidebarItemCategoryLink | undefined,
62
+ ): string | undefined {
63
+ switch (link?.type) {
64
+ case 'doc':
65
+ return getDocById(link.id).permalink;
66
+ case 'generated-index':
67
+ return link.permalink;
68
+ default:
69
+ return undefined;
70
+ }
71
+ }
72
+
73
+ function convertCategory(item: SidebarItemCategory): PropSidebarItemCategory {
74
+ const {link, ...rest} = item;
75
+ const href = getCategoryLinkHref(link);
76
+ return {...rest, items: item.items.map(normalizeItem), ...(href && {href})};
77
+ }
78
+
79
+ function normalizeItem(item: SidebarItem): PropSidebarItem {
51
80
  switch (item.type) {
52
81
  case 'category':
53
- return {...item, items: item.items.map(normalizeItem)};
82
+ return convertCategory(item);
54
83
  case 'ref':
55
84
  case 'doc':
56
85
  return convertDocLink(item);
@@ -58,7 +87,7 @@ Available document ids are:
58
87
  default:
59
88
  return item;
60
89
  }
61
- };
90
+ }
62
91
 
63
92
  // Transform the sidebar so that all sidebar item will be in the
64
93
  // form of 'link' or 'category' only.
@@ -66,6 +95,18 @@ Available document ids are:
66
95
  return mapValues(loadedVersion.sidebars, (items) => items.map(normalizeItem));
67
96
  }
68
97
 
98
+ function toVersionDocsProp(loadedVersion: LoadedVersion): PropVersionDocs {
99
+ return mapValues(
100
+ keyBy(loadedVersion.docs, (doc) => doc.unversionedId),
101
+ (doc) => ({
102
+ id: doc.unversionedId,
103
+ title: doc.title,
104
+ description: doc.description,
105
+ sidebar: doc.sidebar,
106
+ }),
107
+ );
108
+ }
109
+
69
110
  export function toVersionMetadataProp(
70
111
  pluginId: string,
71
112
  loadedVersion: LoadedVersion,
@@ -75,7 +116,41 @@ export function toVersionMetadataProp(
75
116
  version: loadedVersion.versionName,
76
117
  label: loadedVersion.versionLabel,
77
118
  banner: loadedVersion.versionBanner,
119
+ badge: loadedVersion.versionBadge,
120
+ className: loadedVersion.versionClassName,
78
121
  isLast: loadedVersion.isLast,
79
122
  docsSidebars: toSidebarsProp(loadedVersion),
123
+ docs: toVersionDocsProp(loadedVersion),
124
+ };
125
+ }
126
+
127
+ export function toTagDocListProp({
128
+ allTagsPath,
129
+ tag,
130
+ docs,
131
+ }: {
132
+ allTagsPath: string;
133
+ tag: VersionTag;
134
+ docs: Pick<DocMetadata, 'id' | 'title' | 'description' | 'permalink'>[];
135
+ }): PropTagDocList {
136
+ function toDocListProp(): PropTagDocListDoc[] {
137
+ const list = compact(
138
+ tag.docIds.map((id) => docs.find((doc) => doc.id === id)),
139
+ );
140
+ // Sort docs by title
141
+ list.sort((doc1, doc2) => doc1.title.localeCompare(doc2.title));
142
+ return list.map((doc) => ({
143
+ id: doc.id,
144
+ title: doc.title,
145
+ description: doc.description,
146
+ permalink: doc.permalink,
147
+ }));
148
+ }
149
+
150
+ return {
151
+ name: tag.name,
152
+ permalink: tag.permalink,
153
+ docs: toDocListProp(),
154
+ allTagsPath,
80
155
  };
81
156
  }
package/src/routes.ts ADDED
@@ -0,0 +1,173 @@
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 {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
9
+ import {docuHash, createSlugger} from '@docusaurus/utils';
10
+ import {
11
+ CategoryGeneratedIndexMetadata,
12
+ DocMetadata,
13
+ LoadedVersion,
14
+ } from './types';
15
+ import type {PropCategoryGeneratedIndex} from '@docusaurus/plugin-content-docs';
16
+ import {toVersionMetadataProp} from './props';
17
+ import chalk from 'chalk';
18
+
19
+ export async function createCategoryGeneratedIndexRoutes({
20
+ version,
21
+ actions,
22
+ docCategoryGeneratedIndexComponent,
23
+ }: {
24
+ version: LoadedVersion;
25
+ actions: PluginContentLoadedActions;
26
+ docCategoryGeneratedIndexComponent: string;
27
+ }): Promise<RouteConfig[]> {
28
+ const slugs = createSlugger();
29
+
30
+ async function createCategoryGeneratedIndexRoute(
31
+ categoryGeneratedIndex: CategoryGeneratedIndexMetadata,
32
+ ): Promise<RouteConfig> {
33
+ const {sidebar, title, description, slug, permalink, previous, next} =
34
+ categoryGeneratedIndex;
35
+
36
+ const propFileName = slugs.slug(
37
+ `${version.versionPath}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`,
38
+ );
39
+
40
+ const prop: PropCategoryGeneratedIndex = {
41
+ title,
42
+ description,
43
+ slug,
44
+ permalink,
45
+ navigation: {
46
+ previous,
47
+ next,
48
+ },
49
+ };
50
+
51
+ const propData = await actions.createData(
52
+ `${docuHash(`category/${propFileName}`)}.json`,
53
+ JSON.stringify(prop, null, 2),
54
+ );
55
+
56
+ return {
57
+ path: permalink,
58
+ component: docCategoryGeneratedIndexComponent,
59
+ exact: true,
60
+ modules: {
61
+ categoryGeneratedIndex: propData,
62
+ },
63
+ // Same as doc, this sidebar route attribute permits to associate this subpage to the given sidebar
64
+ ...(sidebar && {sidebar}),
65
+ };
66
+ }
67
+
68
+ return Promise.all(
69
+ version.categoryGeneratedIndices.map(createCategoryGeneratedIndexRoute),
70
+ );
71
+ }
72
+
73
+ export async function createDocRoutes({
74
+ docs,
75
+ actions,
76
+ docItemComponent,
77
+ }: {
78
+ docs: DocMetadata[];
79
+ actions: PluginContentLoadedActions;
80
+ docItemComponent: string;
81
+ }): Promise<RouteConfig[]> {
82
+ return Promise.all(
83
+ docs.map(async (metadataItem) => {
84
+ await actions.createData(
85
+ // Note that this created data path must be in sync with
86
+ // metadataPath provided to mdx-loader.
87
+ `${docuHash(metadataItem.source)}.json`,
88
+ JSON.stringify(metadataItem, null, 2),
89
+ );
90
+
91
+ const docRoute: RouteConfig = {
92
+ path: metadataItem.permalink,
93
+ component: docItemComponent,
94
+ exact: true,
95
+ modules: {
96
+ content: metadataItem.source,
97
+ },
98
+ // Because the parent (DocPage) comp need to access it easily
99
+ // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
100
+ ...(metadataItem.sidebar && {
101
+ sidebar: metadataItem.sidebar,
102
+ }),
103
+ };
104
+
105
+ return docRoute;
106
+ }),
107
+ );
108
+ }
109
+
110
+ export async function createVersionRoutes({
111
+ loadedVersion,
112
+ actions,
113
+ docItemComponent,
114
+ docLayoutComponent,
115
+ docCategoryGeneratedIndexComponent,
116
+ pluginId,
117
+ aliasedSource,
118
+ }: {
119
+ loadedVersion: LoadedVersion;
120
+ actions: PluginContentLoadedActions;
121
+ docLayoutComponent: string;
122
+ docItemComponent: string;
123
+ docCategoryGeneratedIndexComponent: string;
124
+ pluginId: string;
125
+ aliasedSource: (str: string) => string;
126
+ }): Promise<void> {
127
+ async function doCreateVersionRoutes(version: LoadedVersion): Promise<void> {
128
+ const versionMetadata = toVersionMetadataProp(pluginId, version);
129
+ const versionMetadataPropPath = await actions.createData(
130
+ `${docuHash(`version-${version.versionName}-metadata-prop`)}.json`,
131
+ JSON.stringify(versionMetadata, null, 2),
132
+ );
133
+
134
+ async function createVersionSubRoutes() {
135
+ const [docRoutes, sidebarsRoutes] = await Promise.all([
136
+ createDocRoutes({docs: version.docs, actions, docItemComponent}),
137
+ createCategoryGeneratedIndexRoutes({
138
+ version,
139
+ actions,
140
+ docCategoryGeneratedIndexComponent,
141
+ }),
142
+ ]);
143
+
144
+ const routes = [...docRoutes, ...sidebarsRoutes];
145
+ return routes.sort((a, b) => a.path.localeCompare(b.path));
146
+ }
147
+
148
+ actions.addRoute({
149
+ path: version.versionPath,
150
+ // allow matching /docs/* as well
151
+ exact: false,
152
+ // main docs component (DocPage)
153
+ component: docLayoutComponent,
154
+ // sub-routes for each doc
155
+ routes: await createVersionSubRoutes(),
156
+ modules: {
157
+ versionMetadata: aliasedSource(versionMetadataPropPath),
158
+ },
159
+ priority: version.routePriority,
160
+ });
161
+ }
162
+
163
+ try {
164
+ return await doCreateVersionRoutes(loadedVersion);
165
+ } catch (e) {
166
+ console.error(
167
+ chalk.red(
168
+ `Can't create version routes for version "${loadedVersion.versionName}"`,
169
+ ),
170
+ );
171
+ throw e;
172
+ }
173
+ }