@docusaurus/plugin-content-docs 0.0.0-4240 → 0.0.0-4244

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 (62) 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.js +5 -23
  5. package/lib/docs.d.ts +22 -2
  6. package/lib/docs.js +71 -29
  7. package/lib/index.js +34 -62
  8. package/lib/options.js +2 -0
  9. package/lib/props.js +35 -6
  10. package/lib/routes.d.ts +27 -0
  11. package/lib/routes.js +105 -0
  12. package/lib/sidebars/generator.d.ts +2 -1
  13. package/lib/sidebars/generator.js +55 -13
  14. package/lib/sidebars/index.d.ts +5 -4
  15. package/lib/sidebars/index.js +18 -9
  16. package/lib/sidebars/normalization.d.ts +8 -3
  17. package/lib/sidebars/normalization.js +36 -17
  18. package/lib/sidebars/processor.d.ts +5 -3
  19. package/lib/sidebars/processor.js +33 -18
  20. package/lib/sidebars/types.d.ts +43 -2
  21. package/lib/sidebars/utils.d.ts +18 -6
  22. package/lib/sidebars/utils.js +149 -24
  23. package/lib/sidebars/validation.d.ts +2 -0
  24. package/lib/sidebars/validation.js +44 -8
  25. package/lib/slug.d.ts +4 -3
  26. package/lib/slug.js +26 -14
  27. package/lib/translations.js +51 -7
  28. package/lib/types.d.ts +18 -3
  29. package/package.json +8 -8
  30. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
  31. package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -106
  32. package/src/__tests__/__snapshots__/index.test.ts.snap +279 -28
  33. package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -0
  34. package/src/__tests__/docs.test.ts +122 -7
  35. package/src/__tests__/index.test.ts +27 -1
  36. package/src/__tests__/options.test.ts +2 -0
  37. package/src/__tests__/slug.test.ts +127 -20
  38. package/src/__tests__/translations.test.ts +7 -0
  39. package/src/categoryGeneratedIndex.ts +57 -0
  40. package/src/cli.ts +5 -35
  41. package/src/docs.ts +103 -45
  42. package/src/index.ts +55 -93
  43. package/src/options.ts +4 -0
  44. package/src/plugin-content-docs.d.ts +71 -8
  45. package/src/props.ts +48 -9
  46. package/src/routes.ts +173 -0
  47. package/src/sidebars/__tests__/__snapshots__/index.test.ts.snap +21 -6
  48. package/src/sidebars/__tests__/generator.test.ts +105 -1
  49. package/src/sidebars/__tests__/index.test.ts +26 -24
  50. package/src/sidebars/__tests__/processor.test.ts +110 -19
  51. package/src/sidebars/__tests__/utils.test.ts +320 -20
  52. package/src/sidebars/__tests__/validation.test.ts +105 -0
  53. package/src/sidebars/generator.ts +82 -19
  54. package/src/sidebars/index.ts +23 -13
  55. package/src/sidebars/normalization.ts +47 -23
  56. package/src/sidebars/processor.ts +57 -27
  57. package/src/sidebars/types.ts +64 -3
  58. package/src/sidebars/utils.ts +217 -42
  59. package/src/sidebars/validation.ts +52 -8
  60. package/src/slug.ts +32 -17
  61. package/src/translations.ts +74 -8
  62. package/src/types.ts +22 -5
package/lib/docs.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.handleNavigation = exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
9
+ exports.createDocsByIdIndex = exports.getDocIds = exports.isConventionalDocIndex = exports.getMainDocId = exports.addDocNavigation = exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const path_1 = (0, tslib_1.__importDefault)(require("path"));
12
12
  const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
@@ -116,7 +116,8 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
116
116
  ? '/'
117
117
  : (0, slug_1.default)({
118
118
  baseID,
119
- dirName: sourceDirName,
119
+ source,
120
+ sourceDirName,
120
121
  frontmatterSlug: frontMatter.slug,
121
122
  stripDirNumberPrefixes: parseNumberPrefixes,
122
123
  numberPrefixParser: options.numberPrefixParser,
@@ -184,44 +185,48 @@ function processDocMetadata(args) {
184
185
  }
185
186
  }
186
187
  exports.processDocMetadata = processDocMetadata;
187
- function handleNavigation(docsBase, sidebars, sidebarFilePath) {
188
- const docsBaseById = (0, lodash_1.keyBy)(docsBase, (doc) => doc.id);
189
- const { checkSidebarsDocIds, getDocNavigation, getFirstDocIdOfFirstSidebar } = (0, utils_2.createSidebarsUtils)(sidebars);
190
- const validDocIds = Object.keys(docsBaseById);
191
- checkSidebarsDocIds(validDocIds, sidebarFilePath);
188
+ function addDocNavigation(docsBase, sidebarsUtils, sidebarFilePath) {
189
+ const docsById = createDocsByIdIndex(docsBase);
190
+ sidebarsUtils.checkSidebarsDocIds(docsBase.flatMap(getDocIds), sidebarFilePath);
192
191
  // Add sidebar/next/previous to the docs
193
192
  function addNavData(doc) {
194
- const { sidebarName, previousId, nextId } = getDocNavigation(doc.id);
195
- const toDocNavLink = (docId, type) => {
196
- var _a;
193
+ const navigation = sidebarsUtils.getDocNavigation(doc.unversionedId, doc.id);
194
+ const toNavigationLinkByDocId = (docId, type) => {
197
195
  if (!docId) {
198
196
  return undefined;
199
197
  }
200
- if (!docsBaseById[docId]) {
198
+ const navDoc = docsById[docId];
199
+ if (!navDoc) {
201
200
  // This could only happen if user provided the ID through front matter
202
201
  throw new Error(`Error when loading ${doc.id} in ${doc.sourceDirName}: the pagination_${type} front matter points to a non-existent ID ${docId}.`);
203
202
  }
204
- const { title, permalink, frontMatter: { pagination_label: paginationLabel, sidebar_label: sidebarLabel, }, } = docsBaseById[docId];
205
- return { title: (_a = paginationLabel !== null && paginationLabel !== void 0 ? paginationLabel : sidebarLabel) !== null && _a !== void 0 ? _a : title, permalink };
203
+ return (0, utils_2.toDocNavigationLink)(navDoc);
206
204
  };
207
- const { frontMatter: { pagination_next: paginationNext = nextId, pagination_prev: paginationPrev = previousId, }, } = doc;
208
- const previous = toDocNavLink(paginationPrev, 'prev');
209
- const next = toDocNavLink(paginationNext, 'next');
210
- return { ...doc, sidebar: sidebarName, previous, next };
205
+ const previous = doc.frontMatter.pagination_prev
206
+ ? toNavigationLinkByDocId(doc.frontMatter.pagination_prev, 'prev')
207
+ : (0, utils_2.toNavigationLink)(navigation.previous, docsById);
208
+ const next = doc.frontMatter.pagination_next
209
+ ? toNavigationLinkByDocId(doc.frontMatter.pagination_next, 'next')
210
+ : (0, utils_2.toNavigationLink)(navigation.next, docsById);
211
+ return { ...doc, sidebar: navigation.sidebarName, previous, next };
211
212
  }
212
- const docs = docsBase.map(addNavData);
213
+ const docsWithNavigation = docsBase.map(addNavData);
213
214
  // sort to ensure consistent output for tests
214
- docs.sort((a, b) => a.id.localeCompare(b.id));
215
- /**
216
- * The "main doc" is the "version entry point"
217
- * We browse this doc by clicking on a version:
218
- * - the "home" doc (at '/docs/')
219
- * - the first doc of the first sidebar
220
- * - a random doc (if no docs are in any sidebar... edge case)
221
- */
215
+ docsWithNavigation.sort((a, b) => a.id.localeCompare(b.id));
216
+ return docsWithNavigation;
217
+ }
218
+ exports.addDocNavigation = addDocNavigation;
219
+ /**
220
+ * The "main doc" is the "version entry point"
221
+ * We browse this doc by clicking on a version:
222
+ * - the "home" doc (at '/docs/')
223
+ * - the first doc of the first sidebar
224
+ * - a random doc (if no docs are in any sidebar... edge case)
225
+ */
226
+ function getMainDocId({ docs, sidebarsUtils, }) {
222
227
  function getMainDoc() {
223
228
  const versionHomeDoc = docs.find((doc) => doc.slug === '/');
224
- const firstDocIdOfFirstSidebar = getFirstDocIdOfFirstSidebar();
229
+ const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
225
230
  if (versionHomeDoc) {
226
231
  return versionHomeDoc;
227
232
  }
@@ -232,6 +237,43 @@ function handleNavigation(docsBase, sidebars, sidebarFilePath) {
232
237
  return docs[0];
233
238
  }
234
239
  }
235
- return { mainDocId: getMainDoc().unversionedId, docs };
240
+ return getMainDoc().unversionedId;
241
+ }
242
+ exports.getMainDocId = getMainDocId;
243
+ function getLastPathSegment(str) {
244
+ return (0, lodash_1.last)(str.split('/'));
245
+ }
246
+ // By convention, Docusaurus considers some docs are "indexes":
247
+ // - index.md
248
+ // - readme.md
249
+ // - <folder>/<folder>.md
250
+ //
251
+ // Those index docs produce a different behavior
252
+ // - Slugs do not end with a weird "/index" suffix
253
+ // - Auto-generated sidebar categories link to them as intro
254
+ function isConventionalDocIndex(doc) {
255
+ // "@site/docs/folder/subFolder/subSubFolder/myDoc.md" => "myDoc"
256
+ const docName = path_1.default.parse(doc.source).name;
257
+ // "folder/subFolder/subSubFolder" => "subSubFolder"
258
+ const lastDirName = getLastPathSegment(doc.sourceDirName);
259
+ const eligibleDocIndexNames = ['index', 'readme', lastDirName.toLowerCase()];
260
+ return eligibleDocIndexNames.includes(docName.toLowerCase());
261
+ }
262
+ exports.isConventionalDocIndex = isConventionalDocIndex;
263
+ // Return both doc ids
264
+ // TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
265
+ // ("id" should be removed & "versionedId" should be renamed to "id")
266
+ function getDocIds(doc) {
267
+ return [doc.unversionedId, doc.id];
268
+ }
269
+ exports.getDocIds = getDocIds;
270
+ // docs are indexed by both versioned and unversioned ids at the same time
271
+ // TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
272
+ // ("id" should be removed & "versionedId" should be renamed to "id")
273
+ function createDocsByIdIndex(docs) {
274
+ return {
275
+ ...(0, lodash_1.keyBy)(docs, (doc) => doc.unversionedId),
276
+ ...(0, lodash_1.keyBy)(docs, (doc) => doc.id),
277
+ };
236
278
  }
237
- exports.handleNavigation = handleNavigation;
279
+ exports.createDocsByIdIndex = createDocsByIdIndex;
package/lib/index.js CHANGED
@@ -23,6 +23,9 @@ const props_1 = require("./props");
23
23
  const translations_1 = require("./translations");
24
24
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
25
25
  const tags_1 = require("./tags");
26
+ const routes_1 = require("./routes");
27
+ const utils_2 = require("./sidebars/utils");
28
+ const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
26
29
  function pluginContentDocs(context, options) {
27
30
  var _a;
28
31
  const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
@@ -95,21 +98,28 @@ function pluginContentDocs(context, options) {
95
98
  return Promise.all(docFiles.map(processVersionDoc));
96
99
  }
97
100
  async function doLoadVersion(versionMetadata) {
98
- const docsBase = await loadVersionDocsBase(versionMetadata);
101
+ const docs = await loadVersionDocsBase(versionMetadata);
99
102
  const sidebars = await (0, sidebars_1.loadSidebars)(versionMetadata.sidebarFilePath, {
100
103
  sidebarItemsGenerator: options.sidebarItemsGenerator,
101
104
  numberPrefixParser: options.numberPrefixParser,
102
- docs: docsBase,
105
+ docs,
103
106
  version: versionMetadata,
104
- options: {
107
+ sidebarOptions: {
105
108
  sidebarCollapsed: options.sidebarCollapsed,
106
109
  sidebarCollapsible: options.sidebarCollapsible,
107
110
  },
111
+ categoryLabelSlugger: (0, utils_1.createSlugger)(),
108
112
  });
113
+ const sidebarsUtils = (0, utils_2.createSidebarsUtils)(sidebars);
109
114
  return {
110
115
  ...versionMetadata,
111
- ...(0, docs_1.handleNavigation)(docsBase, sidebars, versionMetadata.sidebarFilePath),
116
+ docs: (0, docs_1.addDocNavigation)(docs, sidebarsUtils, versionMetadata.sidebarFilePath),
112
117
  sidebars,
118
+ mainDocId: (0, docs_1.getMainDocId)({ docs, sidebarsUtils }),
119
+ categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
120
+ docs,
121
+ sidebarsUtils,
122
+ }),
113
123
  };
114
124
  }
115
125
  async function loadVersion(versionMetadata) {
@@ -130,33 +140,11 @@ function pluginContentDocs(context, options) {
130
140
  },
131
141
  async contentLoaded({ content, actions }) {
132
142
  const { loadedVersions } = content;
133
- const { docLayoutComponent, docItemComponent } = options;
143
+ const { docLayoutComponent, docItemComponent, docCategoryGeneratedIndexComponent, } = options;
134
144
  const { addRoute, createData, setGlobalData } = actions;
135
- const createDocRoutes = async (docs) => {
136
- const routes = await Promise.all(docs.map(async (metadataItem) => {
137
- await createData(
138
- // Note that this created data path must be in sync with
139
- // metadataPath provided to mdx-loader.
140
- `${(0, utils_1.docuHash)(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
141
- const docRoute = {
142
- path: metadataItem.permalink,
143
- component: docItemComponent,
144
- exact: true,
145
- modules: {
146
- content: metadataItem.source,
147
- },
148
- // Because the parent (DocPage) comp need to access it easily
149
- // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
150
- ...(metadataItem.sidebar && {
151
- sidebar: metadataItem.sidebar,
152
- }),
153
- };
154
- return docRoute;
155
- }));
156
- return routes.sort((a, b) => a.path.localeCompare(b.path));
157
- };
158
- async function createVersionTagsRoutes(loadedVersion) {
159
- const versionTags = (0, tags_1.getVersionTags)(loadedVersion.docs);
145
+ async function createVersionTagsRoutes(version) {
146
+ const versionTags = (0, tags_1.getVersionTags)(version.docs);
147
+ // TODO tags should be a sub route of the version route
160
148
  async function createTagsListPage() {
161
149
  const tagsProp = Object.values(versionTags).map((tagValue) => ({
162
150
  name: tagValue.name,
@@ -165,9 +153,9 @@ function pluginContentDocs(context, options) {
165
153
  }));
166
154
  // Only create /tags page if there are tags.
167
155
  if (Object.keys(tagsProp).length > 0) {
168
- const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`tags-list-${loadedVersion.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
156
+ const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`tags-list-${version.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
169
157
  addRoute({
170
- path: loadedVersion.tagsPath,
158
+ path: version.tagsPath,
171
159
  exact: true,
172
160
  component: options.docTagsListComponent,
173
161
  modules: {
@@ -176,11 +164,12 @@ function pluginContentDocs(context, options) {
176
164
  });
177
165
  }
178
166
  }
167
+ // TODO tags should be a sub route of the version route
179
168
  async function createTagDocListPage(tag) {
180
169
  const tagProps = (0, props_1.toTagDocListProp)({
181
- allTagsPath: loadedVersion.tagsPath,
170
+ allTagsPath: version.tagsPath,
182
171
  tag,
183
- docs: loadedVersion.docs,
172
+ docs: version.docs,
184
173
  });
185
174
  const tagPropPath = await createData(`${(0, utils_1.docuHash)(`tag-${tag.permalink}`)}.json`, JSON.stringify(tagProps, null, 2));
186
175
  addRoute({
@@ -195,34 +184,17 @@ function pluginContentDocs(context, options) {
195
184
  await createTagsListPage();
196
185
  await Promise.all(Object.values(versionTags).map(createTagDocListPage));
197
186
  }
198
- async function doCreateVersionRoutes(loadedVersion) {
199
- await createVersionTagsRoutes(loadedVersion);
200
- const versionMetadata = (0, props_1.toVersionMetadataProp)(pluginId, loadedVersion);
201
- const versionMetadataPropPath = await createData(`${(0, utils_1.docuHash)(`version-${loadedVersion.versionName}-metadata-prop`)}.json`, JSON.stringify(versionMetadata, null, 2));
202
- addRoute({
203
- path: loadedVersion.versionPath,
204
- // allow matching /docs/* as well
205
- exact: false,
206
- // main docs component (DocPage)
207
- component: docLayoutComponent,
208
- // sub-routes for each doc
209
- routes: await createDocRoutes(loadedVersion.docs),
210
- modules: {
211
- versionMetadata: aliasedSource(versionMetadataPropPath),
212
- },
213
- priority: loadedVersion.routePriority,
214
- });
215
- }
216
- async function createVersionRoutes(loadedVersion) {
217
- try {
218
- return await doCreateVersionRoutes(loadedVersion);
219
- }
220
- catch (e) {
221
- console.error(chalk_1.default.red(`Can't create version routes for version "${loadedVersion.versionName}"`));
222
- throw e;
223
- }
224
- }
225
- await Promise.all(loadedVersions.map(createVersionRoutes));
187
+ await Promise.all(loadedVersions.map((loadedVersion) => (0, routes_1.createVersionRoutes)({
188
+ loadedVersion,
189
+ docItemComponent,
190
+ docLayoutComponent,
191
+ docCategoryGeneratedIndexComponent,
192
+ pluginId,
193
+ aliasedSource,
194
+ actions,
195
+ })));
196
+ // TODO tags should be a sub route of the version route
197
+ await Promise.all(loadedVersions.map(createVersionTagsRoutes));
226
198
  setGlobalData({
227
199
  path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
228
200
  versions: loadedVersions.map(globalData_1.toGlobalDataVersion),
package/lib/options.js CHANGED
@@ -21,6 +21,7 @@ exports.DEFAULT_OPTIONS = {
21
21
  docItemComponent: '@theme/DocItem',
22
22
  docTagDocListComponent: '@theme/DocTagDocListPage',
23
23
  docTagsListComponent: '@theme/DocTagsListPage',
24
+ docCategoryGeneratedIndexComponent: '@theme/DocCategoryGeneratedIndexPage',
24
25
  remarkPlugins: [],
25
26
  rehypePlugins: [],
26
27
  beforeDefaultRemarkPlugins: [],
@@ -75,6 +76,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
75
76
  docItemComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docItemComponent),
76
77
  docTagsListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagsListComponent),
77
78
  docTagDocListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagDocListComponent),
79
+ docCategoryGeneratedIndexComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docCategoryGeneratedIndexComponent),
78
80
  remarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.remarkPlugins),
79
81
  rehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.rehypePlugins),
80
82
  beforeDefaultRemarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.beforeDefaultRemarkPlugins),
package/lib/props.js CHANGED
@@ -8,16 +8,20 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.toTagDocListProp = exports.toVersionMetadataProp = exports.toSidebarsProp = void 0;
10
10
  const lodash_1 = require("lodash");
11
+ const docs_1 = require("./docs");
11
12
  function toSidebarsProp(loadedVersion) {
12
- const docsById = (0, lodash_1.keyBy)(loadedVersion.docs, (doc) => doc.id);
13
- const convertDocLink = (item) => {
14
- const docId = item.id;
13
+ const docsById = (0, docs_1.createDocsByIdIndex)(loadedVersion.docs);
14
+ function getDocById(docId) {
15
15
  const docMetadata = docsById[docId];
16
16
  if (!docMetadata) {
17
17
  throw new Error(`Invalid sidebars file. The document with id "${docId}" was used in the sidebar, but no document with this id could be found.
18
18
  Available document ids are:
19
19
  - ${Object.keys(docsById).sort().join('\n- ')}`);
20
20
  }
21
+ return docMetadata;
22
+ }
23
+ const convertDocLink = (item) => {
24
+ const docMetadata = getDocById(item.id);
21
25
  const { title, permalink, frontMatter: { sidebar_label: sidebarLabel }, } = docMetadata;
22
26
  return {
23
27
  type: 'link',
@@ -25,12 +29,28 @@ Available document ids are:
25
29
  href: permalink,
26
30
  className: item.className,
27
31
  customProps: item.customProps,
32
+ docId: docMetadata.unversionedId,
28
33
  };
29
34
  };
30
- const normalizeItem = (item) => {
35
+ function getCategoryLinkHref(link) {
36
+ switch (link === null || link === void 0 ? void 0 : link.type) {
37
+ case 'doc':
38
+ return getDocById(link.id).permalink;
39
+ case 'generated-index':
40
+ return link.permalink;
41
+ default:
42
+ return undefined;
43
+ }
44
+ }
45
+ function convertCategory(item) {
46
+ const { link, ...rest } = item;
47
+ const href = getCategoryLinkHref(link);
48
+ return { ...rest, items: item.items.map(normalizeItem), ...(href && { href }) };
49
+ }
50
+ function normalizeItem(item) {
31
51
  switch (item.type) {
32
52
  case 'category':
33
- return { ...item, items: item.items.map(normalizeItem) };
53
+ return convertCategory(item);
34
54
  case 'ref':
35
55
  case 'doc':
36
56
  return convertDocLink(item);
@@ -38,13 +58,21 @@ Available document ids are:
38
58
  default:
39
59
  return item;
40
60
  }
41
- };
61
+ }
42
62
  // Transform the sidebar so that all sidebar item will be in the
43
63
  // form of 'link' or 'category' only.
44
64
  // This is what will be passed as props to the UI component.
45
65
  return (0, lodash_1.mapValues)(loadedVersion.sidebars, (items) => items.map(normalizeItem));
46
66
  }
47
67
  exports.toSidebarsProp = toSidebarsProp;
68
+ function toVersionDocsProp(loadedVersion) {
69
+ return (0, lodash_1.mapValues)((0, lodash_1.keyBy)(loadedVersion.docs, (doc) => doc.unversionedId), (doc) => ({
70
+ id: doc.unversionedId,
71
+ title: doc.title,
72
+ description: doc.description,
73
+ sidebar: doc.sidebar,
74
+ }));
75
+ }
48
76
  function toVersionMetadataProp(pluginId, loadedVersion) {
49
77
  return {
50
78
  pluginId,
@@ -55,6 +83,7 @@ function toVersionMetadataProp(pluginId, loadedVersion) {
55
83
  className: loadedVersion.versionClassName,
56
84
  isLast: loadedVersion.isLast,
57
85
  docsSidebars: toSidebarsProp(loadedVersion),
86
+ docs: toVersionDocsProp(loadedVersion),
58
87
  };
59
88
  }
60
89
  exports.toVersionMetadataProp = toVersionMetadataProp;
@@ -0,0 +1,27 @@
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
+ import { PluginContentLoadedActions, RouteConfig } from '@docusaurus/types';
8
+ import { DocMetadata, LoadedVersion } from './types';
9
+ export declare function createCategoryGeneratedIndexRoutes({ version, actions, docCategoryGeneratedIndexComponent, }: {
10
+ version: LoadedVersion;
11
+ actions: PluginContentLoadedActions;
12
+ docCategoryGeneratedIndexComponent: string;
13
+ }): Promise<RouteConfig[]>;
14
+ export declare function createDocRoutes({ docs, actions, docItemComponent, }: {
15
+ docs: DocMetadata[];
16
+ actions: PluginContentLoadedActions;
17
+ docItemComponent: string;
18
+ }): Promise<RouteConfig[]>;
19
+ export declare function createVersionRoutes({ loadedVersion, actions, docItemComponent, docLayoutComponent, docCategoryGeneratedIndexComponent, pluginId, aliasedSource, }: {
20
+ loadedVersion: LoadedVersion;
21
+ actions: PluginContentLoadedActions;
22
+ docLayoutComponent: string;
23
+ docItemComponent: string;
24
+ docCategoryGeneratedIndexComponent: string;
25
+ pluginId: string;
26
+ aliasedSource: (str: string) => string;
27
+ }): Promise<void>;
package/lib/routes.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createVersionRoutes = exports.createDocRoutes = exports.createCategoryGeneratedIndexRoutes = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const utils_1 = require("@docusaurus/utils");
12
+ const props_1 = require("./props");
13
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
14
+ async function createCategoryGeneratedIndexRoutes({ version, actions, docCategoryGeneratedIndexComponent, }) {
15
+ const slugs = (0, utils_1.createSlugger)();
16
+ async function createCategoryGeneratedIndexRoute(categoryGeneratedIndex) {
17
+ const { sidebar, title, description, slug, permalink, previous, next } = categoryGeneratedIndex;
18
+ const propFileName = slugs.slug(`${version.versionPath}-${categoryGeneratedIndex.sidebar}-category-${categoryGeneratedIndex.title}`);
19
+ const prop = {
20
+ title,
21
+ description,
22
+ slug,
23
+ permalink,
24
+ navigation: {
25
+ previous,
26
+ next,
27
+ },
28
+ };
29
+ const propData = await actions.createData(`${(0, utils_1.docuHash)(`category/${propFileName}`)}.json`, JSON.stringify(prop, null, 2));
30
+ return {
31
+ path: permalink,
32
+ component: docCategoryGeneratedIndexComponent,
33
+ exact: true,
34
+ modules: {
35
+ categoryGeneratedIndex: propData,
36
+ },
37
+ // Same as doc, this sidebar route attribute permits to associate this subpage to the given sidebar
38
+ ...(sidebar && { sidebar }),
39
+ };
40
+ }
41
+ return Promise.all(version.categoryGeneratedIndices.map(createCategoryGeneratedIndexRoute));
42
+ }
43
+ exports.createCategoryGeneratedIndexRoutes = createCategoryGeneratedIndexRoutes;
44
+ async function createDocRoutes({ docs, actions, docItemComponent, }) {
45
+ return Promise.all(docs.map(async (metadataItem) => {
46
+ await actions.createData(
47
+ // Note that this created data path must be in sync with
48
+ // metadataPath provided to mdx-loader.
49
+ `${(0, utils_1.docuHash)(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
50
+ const docRoute = {
51
+ path: metadataItem.permalink,
52
+ component: docItemComponent,
53
+ exact: true,
54
+ modules: {
55
+ content: metadataItem.source,
56
+ },
57
+ // Because the parent (DocPage) comp need to access it easily
58
+ // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
59
+ ...(metadataItem.sidebar && {
60
+ sidebar: metadataItem.sidebar,
61
+ }),
62
+ };
63
+ return docRoute;
64
+ }));
65
+ }
66
+ exports.createDocRoutes = createDocRoutes;
67
+ async function createVersionRoutes({ loadedVersion, actions, docItemComponent, docLayoutComponent, docCategoryGeneratedIndexComponent, pluginId, aliasedSource, }) {
68
+ async function doCreateVersionRoutes(version) {
69
+ const versionMetadata = (0, props_1.toVersionMetadataProp)(pluginId, version);
70
+ const versionMetadataPropPath = await actions.createData(`${(0, utils_1.docuHash)(`version-${version.versionName}-metadata-prop`)}.json`, JSON.stringify(versionMetadata, null, 2));
71
+ async function createVersionSubRoutes() {
72
+ const [docRoutes, sidebarsRoutes] = await Promise.all([
73
+ createDocRoutes({ docs: version.docs, actions, docItemComponent }),
74
+ createCategoryGeneratedIndexRoutes({
75
+ version,
76
+ actions,
77
+ docCategoryGeneratedIndexComponent,
78
+ }),
79
+ ]);
80
+ const routes = [...docRoutes, ...sidebarsRoutes];
81
+ return routes.sort((a, b) => a.path.localeCompare(b.path));
82
+ }
83
+ actions.addRoute({
84
+ path: version.versionPath,
85
+ // allow matching /docs/* as well
86
+ exact: false,
87
+ // main docs component (DocPage)
88
+ component: docLayoutComponent,
89
+ // sub-routes for each doc
90
+ routes: await createVersionSubRoutes(),
91
+ modules: {
92
+ versionMetadata: aliasedSource(versionMetadataPropPath),
93
+ },
94
+ priority: version.routePriority,
95
+ });
96
+ }
97
+ try {
98
+ return await doCreateVersionRoutes(loadedVersion);
99
+ }
100
+ catch (e) {
101
+ console.error(chalk_1.default.red(`Can't create version routes for version "${loadedVersion.versionName}"`));
102
+ throw e;
103
+ }
104
+ }
105
+ exports.createVersionRoutes = createVersionRoutes;
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import type { SidebarItemsGenerator } from './types';
7
+ import type { SidebarItemsGenerator, SidebarItemCategoryLinkConfig } from './types';
8
8
  export declare const CategoryMetadataFilenameBase = "_category_";
9
9
  export declare const CategoryMetadataFilenamePattern = "_category_.{json,yml,yaml}";
10
10
  export declare type CategoryMetadataFile = {
@@ -13,5 +13,6 @@ export declare type CategoryMetadataFile = {
13
13
  collapsed?: boolean;
14
14
  collapsible?: boolean;
15
15
  className?: string;
16
+ link?: SidebarItemCategoryLinkConfig;
16
17
  };
17
18
  export declare const DefaultSidebarItemsGenerator: SidebarItemsGenerator;