@docusaurus/plugin-content-docs 0.0.0-4518 → 0.0.0-4524

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-docs",
3
- "version": "0.0.0-4518",
3
+ "version": "0.0.0-4524",
4
4
  "description": "Docs plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "exports": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@docusaurus/core": "0.0.0-4518",
26
- "@docusaurus/logger": "0.0.0-4518",
27
- "@docusaurus/mdx-loader": "0.0.0-4518",
28
- "@docusaurus/utils": "0.0.0-4518",
29
- "@docusaurus/utils-validation": "0.0.0-4518",
25
+ "@docusaurus/core": "0.0.0-4524",
26
+ "@docusaurus/logger": "0.0.0-4524",
27
+ "@docusaurus/mdx-loader": "0.0.0-4524",
28
+ "@docusaurus/utils": "0.0.0-4524",
29
+ "@docusaurus/utils-validation": "0.0.0-4524",
30
30
  "combine-promises": "^1.1.0",
31
31
  "fs-extra": "^10.0.0",
32
32
  "import-fresh": "^3.2.2",
@@ -39,8 +39,8 @@
39
39
  "webpack": "^5.61.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@docusaurus/module-type-aliases": "0.0.0-4518",
43
- "@docusaurus/types": "0.0.0-4518",
42
+ "@docusaurus/module-type-aliases": "0.0.0-4524",
43
+ "@docusaurus/types": "0.0.0-4524",
44
44
  "@types/js-yaml": "^4.0.0",
45
45
  "@types/picomatch": "^2.2.1",
46
46
  "commander": "^5.1.0",
@@ -56,5 +56,5 @@
56
56
  "engines": {
57
57
  "node": ">=14"
58
58
  },
59
- "gitHead": "734bca0f3ea8d04fa3b908d56ea0fb159ab47ab3"
59
+ "gitHead": "41a6bff3a67446f7d2a2972cbe4d05fec7378a15"
60
60
  }
package/src/cli.ts CHANGED
@@ -32,10 +32,12 @@ function createVersionedSidebarFile({
32
32
  version: string;
33
33
  }) {
34
34
  // Load current sidebar and create a new versioned sidebars file (if needed).
35
- // Note: we don't need the sidebars file to be normalized: it's ok to let plugin option changes to impact older, versioned sidebars
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
36
37
  const sidebars = loadSidebarsFile(sidebarPath);
37
38
 
38
- // Do not create a useless versioned sidebars file if sidebars file is empty or sidebars are disabled/false)
39
+ // Do not create a useless versioned sidebars file if sidebars file is empty
40
+ // or sidebars are disabled/false)
39
41
  const shouldCreateVersionedSidebarFile = Object.keys(sidebars).length > 0;
40
42
 
41
43
  if (shouldCreateVersionedSidebarFile) {
@@ -28,7 +28,7 @@ export function getActivePlugin(
28
28
  options: GetActivePluginOptions = {},
29
29
  ): ActivePlugin | undefined {
30
30
  const activeEntry = Object.entries(allPluginDatas)
31
- // A quick route sorting: '/android/foo' should match '/android' instead of '/'
31
+ // Route sorting: '/android/foo' should match '/android' instead of '/'
32
32
  .sort((a, b) => b[1].path.localeCompare(a[1].path))
33
33
  .find(
34
34
  ([, pluginData]) =>
@@ -67,7 +67,7 @@ export const getActiveVersion = (
67
67
  ): GlobalVersion | undefined => {
68
68
  const lastVersion = getLatestVersion(data);
69
69
  // Last version is a route like /docs/*,
70
- // 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
71
71
  const orderedVersionsMetadata = [
72
72
  ...data.versions.filter((version) => version !== lastVersion),
73
73
  lastVersion,
@@ -27,12 +27,13 @@ import type {
27
27
  GetActivePluginOptions,
28
28
  } from '@docusaurus/plugin-content-docs/client';
29
29
 
30
- // Important to use a constant object to avoid React useEffect executions etc...,
30
+ // Important to use a constant object to avoid React useEffect executions etc.
31
31
  // see https://github.com/facebook/docusaurus/issues/5089
32
32
  const StableEmptyObject = {};
33
33
 
34
- // Not using useAllPluginInstancesData() because in blog-only mode, docs hooks are still used by the theme
35
- // We need a fail-safe fallback when the docs plugin is not in use
34
+ // Not using useAllPluginInstancesData() because in blog-only mode, docs hooks
35
+ // are still used by the theme. We need a fail-safe fallback when the docs
36
+ // plugin is not in use
36
37
  export const useAllDocsData = (): Record<string, GlobalPluginData> =>
37
38
  // useAllPluginInstancesData('docusaurus-plugin-content-docs');
38
39
  useGlobalData()['docusaurus-plugin-content-docs'] ?? StableEmptyObject;
package/src/docs.ts CHANGED
@@ -139,7 +139,8 @@ function doProcessDocMetadata({
139
139
  const {
140
140
  custom_edit_url: customEditURL,
141
141
 
142
- // Strip number prefixes by default (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc) by default,
142
+ // Strip number prefixes by default
143
+ // (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
143
144
  // but allow to disable this behavior with front matter
144
145
  parse_number_prefixes: parseNumberPrefixes = true,
145
146
  } = frontMatter;
@@ -164,7 +165,8 @@ function doProcessDocMetadata({
164
165
  throw new Error(`Document id "${baseID}" cannot include slash.`);
165
166
  }
166
167
 
167
- // For autogenerated sidebars, sidebar position can come from filename number prefix or front matter
168
+ // For autogenerated sidebars, sidebar position can come from filename number
169
+ // prefix or front matter
168
170
  const sidebarPosition: number | undefined =
169
171
  frontMatter.sidebar_position ?? numberPrefix;
170
172
 
@@ -205,8 +207,9 @@ function doProcessDocMetadata({
205
207
  numberPrefixParser: options.numberPrefixParser,
206
208
  });
207
209
 
208
- // Note: the title is used by default for page title, sidebar label, pagination buttons...
209
- // frontMatter.title should be used in priority over contentTitle (because it can contain markdown/JSX syntax)
210
+ // Note: the title is used by default for page title, sidebar label,
211
+ // pagination buttons... frontMatter.title should be used in priority over
212
+ // contentTitle (because it can contain markdown/JSX syntax)
210
213
  const title: string = frontMatter.title ?? contentTitle ?? baseID;
211
214
 
212
215
  const description: string = frontMatter.description ?? excerpt ?? '';
@@ -233,9 +236,8 @@ function doProcessDocMetadata({
233
236
  ? versionMetadata.versionEditUrlLocalized
234
237
  : versionMetadata.versionEditUrl;
235
238
  return getEditUrl(relativeFilePath, baseVersionEditUrl);
236
- } else {
237
- return undefined;
238
239
  }
240
+ return undefined;
239
241
  }
240
242
 
241
243
  // Assign all of object properties during instantiation (if possible) for
@@ -361,9 +363,8 @@ export function getMainDocId({
361
363
  doc.id === firstDocIdOfFirstSidebar ||
362
364
  doc.unversionedId === firstDocIdOfFirstSidebar,
363
365
  )!;
364
- } else {
365
- return docs[0];
366
366
  }
367
+ return docs[0];
367
368
  }
368
369
 
369
370
  return getMainDoc().unversionedId;
@@ -407,7 +408,8 @@ export function toCategoryIndexMatcherParam({
407
408
  }
408
409
 
409
410
  /**
410
- * guides/sidebar/autogenerated.md -> 'autogenerated', '.md', ['sidebar', 'guides']
411
+ * `guides/sidebar/autogenerated.md` ->
412
+ * `'autogenerated', '.md', ['sidebar', 'guides']`
411
413
  */
412
414
  export function splitPath(str: string): {
413
415
  /**
@@ -428,15 +430,17 @@ export function splitPath(str: string): {
428
430
  }
429
431
 
430
432
  // Return both doc ids
431
- // TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
432
- // ("id" should be removed & "versionedId" should be renamed to "id")
433
+ // TODO legacy retro-compatibility due to old versioned sidebars using
434
+ // versioned doc ids ("id" should be removed & "versionedId" should be renamed
435
+ // to "id")
433
436
  export function getDocIds(doc: DocMetadataBase): [string, string] {
434
437
  return [doc.unversionedId, doc.id];
435
438
  }
436
439
 
437
440
  // docs are indexed by both versioned and unversioned ids at the same time
438
- // TODO legacy retro-compatibility due to old versioned sidebars using versioned doc ids
439
- // ("id" should be removed & "versionedId" should be renamed to "id")
441
+ // TODO legacy retro-compatibility due to old versioned sidebars using
442
+ // versioned doc ids ("id" should be removed & "versionedId" should be renamed
443
+ // to "id")
440
444
  export function createDocsByIdIndex<
441
445
  Doc extends {id: string; unversionedId: string},
442
446
  >(docs: Doc[]): Record<string, Doc> {
@@ -8,15 +8,16 @@
8
8
  import type {NumberPrefixParser} from '@docusaurus/plugin-content-docs';
9
9
 
10
10
  // Best-effort to avoid parsing some patterns as number prefix
11
- const IgnoredPrefixPatterns = (function () {
11
+ const IgnoredPrefixPatterns = (() => {
12
12
  // ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640
13
13
  const DateLikePrefixRegex =
14
14
  /^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/;
15
15
 
16
16
  // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
17
- // note: we could try to parse float numbers in filenames but that is probably not worth it
18
- // as a version such as "8.0" can be interpreted as both a version and a float
19
- // User can configure his own NumberPrefixParser if he wants 8.0 to be interpreted as a float
17
+ // note: we could try to parse float numbers in filenames but that is
18
+ // probably not worth it as a version such as "8.0" can be interpreted as both
19
+ // a version and a float. User can configure her own NumberPrefixParser if
20
+ // she wants 8.0 to be interpreted as a float
20
21
  const VersionLikePrefixRegex = /^(\d+[-_.]\d+)(.*)$/;
21
22
 
22
23
  return new RegExp(
package/src/options.ts CHANGED
@@ -148,8 +148,9 @@ export function validateOptions({
148
148
  let options = userOptions;
149
149
 
150
150
  if (options.sidebarCollapsible === false) {
151
- // When sidebarCollapsible=false and sidebarCollapsed=undefined, we don't want to have the inconsistency warning
152
- // We let options.sidebarCollapsible become the default value for options.sidebarCollapsed
151
+ // When sidebarCollapsible=false and sidebarCollapsed=undefined, we don't
152
+ // want to have the inconsistency warning. We let options.sidebarCollapsible
153
+ // become the default value for options.sidebarCollapsed
153
154
  if (typeof options.sidebarCollapsed === 'undefined') {
154
155
  options = {
155
156
  ...options,
@@ -45,7 +45,8 @@ declare module '@docusaurus/plugin-content-docs' {
45
45
  sidebarPath?: string | false | undefined;
46
46
  };
47
47
 
48
- // TODO support custom version banner? {type: "error", content: "html content"}
48
+ // TODO support custom version banner?
49
+ // {type: "error", content: "html content"}
49
50
  export type VersionBanner = 'unreleased' | 'unmaintained';
50
51
  export type VersionOptions = {
51
52
  path?: string;
package/src/routes.ts CHANGED
@@ -73,7 +73,8 @@ export async function createCategoryGeneratedIndexRoutes({
73
73
  modules: {
74
74
  categoryGeneratedIndex: aliasedSource(propData),
75
75
  },
76
- // Same as doc, this sidebar route attribute permits to associate this subpage to the given sidebar
76
+ // Same as doc, this sidebar route attribute permits to associate this
77
+ // subpage to the given sidebar
77
78
  ...(sidebar && {sidebar}),
78
79
  };
79
80
  }
@@ -109,7 +110,8 @@ export async function createDocRoutes({
109
110
  content: metadataItem.source,
110
111
  },
111
112
  // Because the parent (DocPage) comp need to access it easily
112
- // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
113
+ // This permits to render the sidebar once without unmount/remount when
114
+ // navigating (and preserve sidebar state)
113
115
  ...(metadataItem.sidebar && {
114
116
  sidebar: metadataItem.sidebar,
115
117
  }),
@@ -47,7 +47,8 @@ export type CategoryMetadataFile = {
47
47
  className?: string;
48
48
  link?: SidebarItemCategoryLinkConfig | null;
49
49
 
50
- // TODO should we allow "items" here? how would this work? would an "autogenerated" type be allowed?
50
+ // TODO should we allow "items" here? how would this work? would an
51
+ // "autogenerated" type be allowed?
51
52
  // This mkdocs plugin do something like that: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin/
52
53
  // cf comment: https://github.com/facebook/docusaurus/issues/3464#issuecomment-784765199
53
54
  };
@@ -56,16 +57,20 @@ type WithPosition<T> = T & {position?: number};
56
57
 
57
58
  /**
58
59
  * A representation of the fs structure. For each object entry:
59
- * If it's a folder, the key is the directory name, and value is the directory content;
60
- * If it's a doc file, the key is the doc id prefixed with '$doc$/', and value is null
60
+ * If it's a folder, the key is the directory name, and value is the directory
61
+ * content; If it's a doc file, the key is the doc id prefixed with '$doc$/',
62
+ * and value is null
61
63
  */
62
64
  type Dir = {
63
65
  [item: string]: Dir | null;
64
66
  };
65
67
 
66
- // TODO I now believe we should read all the category metadata files ahead of time: we may need this metadata to customize docs metadata
67
- // 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...
68
- // TODO later if there is `CategoryFolder/with-category-name-doc.md`, we may want to read the metadata as yaml on it
68
+ // TODO I now believe we should read all the category metadata files ahead of
69
+ // time: we may need this metadata to customize docs metadata
70
+ // Example use-case being able to disable number prefix parsing at the folder
71
+ // level, or customize the default base slug for an intermediate directory
72
+ // TODO later if there is `CategoryFolder/with-category-name-doc.md`, we may
73
+ // want to read the metadata as yaml on it
69
74
  // see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
70
75
  async function readCategoryMetadataFile(
71
76
  categoryDirPath: string,
@@ -142,7 +147,8 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
142
147
  * Step 2. Turn the linear file list into a tree structure.
143
148
  */
144
149
  function treeify(docs: SidebarItemsGeneratorDoc[]): Dir {
145
- // Get the category breadcrumb of a doc (relative to the dir of the autogenerated sidebar item)
150
+ // Get the category breadcrumb of a doc (relative to the dir of the
151
+ // autogenerated sidebar item)
146
152
  // autogenDir=a/b and docDir=a/b/c/d => returns [c, d]
147
153
  // autogenDir=a/b and docDir=a/b => returns []
148
154
  // TODO: try to use path.relative()
@@ -169,7 +175,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
169
175
  }
170
176
 
171
177
  /**
172
- * Step 3. Recursively transform the tree-like file structure to sidebar items.
178
+ * Step 3. Recursively transform the tree-like structure to sidebar items.
173
179
  * (From a record to an array of items, akin to normalizing shorthand)
174
180
  */
175
181
  function generateSidebar(fsModel: Dir): Promise<WithPosition<SidebarItem>[]> {
@@ -182,7 +188,8 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
182
188
  type: 'doc',
183
189
  id,
184
190
  position,
185
- // We don't want these fields to magically appear in the generated sidebar
191
+ // We don't want these fields to magically appear in the generated
192
+ // sidebar
186
193
  ...(label !== undefined && {label}),
187
194
  ...(className !== undefined && {className}),
188
195
  };
@@ -225,13 +232,12 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
225
232
  if (link !== undefined) {
226
233
  if (link && link.type === 'doc') {
227
234
  return findDocByLocalId(link.id)?.id || getDoc(link.id).id;
228
- } else {
229
- // We don't continue for other link types on purpose!
230
- // IE if user decide to use type "generated-index", we should not pick a README.md file as the linked doc
231
- return undefined;
232
235
  }
236
+ // If a link is explicitly specified, we won't apply conventions
237
+ return undefined;
233
238
  }
234
- // Apply default convention to pick index.md, README.md or <categoryName>.md as the category doc
239
+ // Apply default convention to pick index.md, README.md or
240
+ // <categoryName>.md as the category doc
235
241
  return findConventionalCategoryDocLink()?.id;
236
242
  }
237
243
 
@@ -279,10 +285,11 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
279
285
  }
280
286
 
281
287
  /**
282
- * Step 4. Recursively sort the categories/docs + remove the "position" attribute from final output.
283
- * Note: the "position" is only used to sort "inside" a sidebar slice. It is not
284
- * used to sort across multiple consecutive sidebar slices (ie a whole Category
285
- * composed of multiple autogenerated items)
288
+ * Step 4. Recursively sort the categories/docs + remove the "position"
289
+ * attribute from final output. Note: the "position" is only used to sort
290
+ * "inside" a sidebar slice. It is not used to sort across multiple
291
+ * consecutive sidebar slices (i.e. a whole category composed of multiple
292
+ * autogenerated items)
286
293
  */
287
294
  function sortItems(sidebarItems: WithPosition<SidebarItem>[]): SidebarItem[] {
288
295
  const processedSidebarItems = sidebarItems.map((item) => {
@@ -298,7 +305,6 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
298
305
  return sortedSidebarItems.map(({position, ...item}) => item);
299
306
  }
300
307
  // TODO: the whole code is designed for pipeline operator
301
- // return getAutogenDocs() |> treeify |> await generateSidebar(^) |> sortItems;
302
308
  const docs = getAutogenDocs();
303
309
  const fsModel = treeify(docs);
304
310
  const sidebarWithPosition = await generateSidebar(fsModel);
@@ -60,7 +60,8 @@ function toSidebarItemsGeneratorVersion(
60
60
  return pick(version, ['versionName', 'contentPath']);
61
61
  }
62
62
 
63
- // Handle the generation of autogenerated sidebar items and other post-processing checks
63
+ // Handle the generation of autogenerated sidebar items and other
64
+ // post-processing checks
64
65
  async function processSidebar(
65
66
  unprocessedSidebar: NormalizedSidebar,
66
67
  params: SidebarProcessorParams,
@@ -91,7 +92,8 @@ async function processSidebar(
91
92
  async function processAutoGeneratedItem(
92
93
  item: SidebarItemAutogenerated,
93
94
  ): Promise<SidebarItem[]> {
94
- // TODO the returned type can't be trusted in practice (generator can be user-provided)
95
+ // TODO the returned type can't be trusted in practice (generator can be
96
+ // user-provided)
95
97
  const generatedItems = await sidebarItemsGenerator({
96
98
  item,
97
99
  numberPrefixParser,
@@ -106,7 +108,8 @@ async function processSidebar(
106
108
  normalizeItem(generatedItem, {...params, ...sidebarOptions}),
107
109
  );
108
110
 
109
- // Process again... weird but sidebar item generated might generate some auto-generated items?
111
+ // Process again... weird but sidebar item generated might generate some
112
+ // auto-generated items?
110
113
  return processItems(generatedItemsNormalized);
111
114
  }
112
115
 
@@ -205,7 +205,8 @@ export type SidebarItemsGenerator = (
205
205
  Promise<SidebarItem[]>;
206
206
  // Promise<SidebarItemConfig[]>;
207
207
 
208
- // Also inject the default generator to conveniently wrap/enhance/sort the default sidebar gen logic
208
+ // Also inject the default generator to conveniently wrap/enhance/sort the
209
+ // default sidebar gen logic
209
210
  // see https://github.com/facebook/docusaurus/issues/4640#issuecomment-822292320
210
211
  export type SidebarItemsGeneratorOptionArgs = {
211
212
  defaultSidebarItemsGenerator: SidebarItemsGenerator;
@@ -16,7 +16,6 @@ import type {
16
16
  SidebarCategoriesShorthand,
17
17
  SidebarItemConfig,
18
18
  SidebarItemCategoryWithGeneratedIndex,
19
- SidebarItemCategoryWithLink,
20
19
  SidebarNavigationItem,
21
20
  } from './types';
22
21
 
@@ -46,8 +45,11 @@ export function transformSidebarItems(
46
45
  return sidebar.map(transformRecursive);
47
46
  }
48
47
 
49
- // Flatten sidebar items into a single flat array (containing categories/docs on the same level)
50
- // /!\ order matters (useful for next/prev nav), top categories appear before their child elements
48
+ /**
49
+ * Flatten sidebar items into a single flat array (containing categories/docs on
50
+ * the same level). Order matters (useful for next/prev nav), top categories
51
+ * appear before their child elements
52
+ */
51
53
  function flattenSidebarItems(items: SidebarItem[]): SidebarItem[] {
52
54
  function flattenRecursive(item: SidebarItem): SidebarItem[] {
53
55
  return item.type === 'category'
@@ -196,34 +198,33 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
196
198
  sidebarName = getSidebarNameByDocId(docId);
197
199
  }
198
200
 
199
- if (sidebarName) {
200
- if (!sidebarNameToNavigationItems[sidebarName]) {
201
- throw new Error(
202
- `Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
203
- );
201
+ if (!sidebarName) {
202
+ return emptySidebarNavigation();
203
+ }
204
+ if (!sidebarNameToNavigationItems[sidebarName]) {
205
+ throw new Error(
206
+ `Doc with ID ${docId} wants to display sidebar ${sidebarName} but a sidebar with this name doesn't exist`,
207
+ );
208
+ }
209
+ const navigationItems = sidebarNameToNavigationItems[sidebarName];
210
+ const currentItemIndex = navigationItems.findIndex((item) => {
211
+ if (item.type === 'doc') {
212
+ return item.id === docId;
204
213
  }
205
- const navigationItems = sidebarNameToNavigationItems[sidebarName];
206
- const currentItemIndex = navigationItems.findIndex((item) => {
207
- if (item.type === 'doc') {
208
- return item.id === docId;
209
- }
210
- if (item.type === 'category' && item.link.type === 'doc') {
211
- return item.link.id === docId;
212
- }
213
- return false;
214
- });
215
- if (currentItemIndex === -1) {
216
- return {sidebarName, next: undefined, previous: undefined};
214
+ if (item.type === 'category' && item.link.type === 'doc') {
215
+ return item.link.id === docId;
217
216
  }
218
-
219
- const {previous, next} = getElementsAround(
220
- navigationItems,
221
- currentItemIndex,
222
- );
223
- return {sidebarName, previous, next};
224
- } else {
225
- return emptySidebarNavigation();
217
+ return false;
218
+ });
219
+ if (currentItemIndex === -1) {
220
+ return {sidebarName, next: undefined, previous: undefined};
226
221
  }
222
+
223
+ const {previous, next} = getElementsAround(
224
+ navigationItems,
225
+ currentItemIndex,
226
+ );
227
+ return {sidebarName, previous, next};
227
228
  }
228
229
 
229
230
  function getCategoryGeneratedIndexList(): SidebarItemCategoryWithGeneratedIndex[] {
@@ -237,8 +238,10 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
237
238
  });
238
239
  }
239
240
 
240
- // We identity the category generated index by its permalink (should be unique)
241
- // More reliable than using object identity
241
+ /**
242
+ * We identity the category generated index by its permalink (should be
243
+ * unique). More reliable than using object identity
244
+ */
242
245
  function getCategoryGeneratedIndexNavigation(
243
246
  categoryGeneratedIndexPermalink: string,
244
247
  ): SidebarNavigation {
@@ -257,19 +260,18 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils {
257
260
  navigationItems.find(isCurrentCategoryGeneratedIndexItem),
258
261
  )?.[0];
259
262
 
260
- if (sidebarName) {
261
- const navigationItems = sidebarNameToNavigationItems[sidebarName];
262
- const currentItemIndex = navigationItems.findIndex(
263
- isCurrentCategoryGeneratedIndexItem,
264
- );
265
- const {previous, next} = getElementsAround(
266
- navigationItems,
267
- currentItemIndex,
268
- );
269
- return {sidebarName, previous, next};
270
- } else {
263
+ if (!sidebarName) {
271
264
  return emptySidebarNavigation();
272
265
  }
266
+ const navigationItems = sidebarNameToNavigationItems[sidebarName];
267
+ const currentItemIndex = navigationItems.findIndex(
268
+ isCurrentCategoryGeneratedIndexItem,
269
+ );
270
+ const {previous, next} = getElementsAround(
271
+ navigationItems,
272
+ currentItemIndex,
273
+ );
274
+ return {sidebarName, previous, next};
273
275
  }
274
276
 
275
277
  function checkSidebarsDocIds(validDocIds: string[], sidebarFilePath: string) {
@@ -322,11 +324,10 @@ Available document ids are:
322
324
  slug: item.link.slug,
323
325
  label: item.label,
324
326
  };
325
- } else {
326
- const firstSubItem = getFirstLink(item.items);
327
- if (firstSubItem) {
328
- return firstSubItem;
329
- }
327
+ }
328
+ const firstSubItem = getFirstLink(item.items);
329
+ if (firstSubItem) {
330
+ return firstSubItem;
330
331
  }
331
332
  }
332
333
  }
@@ -371,18 +372,6 @@ export function toNavigationLink(
371
372
  return doc;
372
373
  }
373
374
 
374
- function handleCategory(category: SidebarItemCategoryWithLink): DocNavLink {
375
- if (category.link.type === 'doc') {
376
- return toDocNavigationLink(getDocById(category.link.id));
377
- } else if (category.link.type === 'generated-index') {
378
- return {
379
- title: category.label,
380
- permalink: category.link.permalink,
381
- };
382
- } else {
383
- throw new Error('unexpected category link type');
384
- }
385
- }
386
375
  if (!navigationItem) {
387
376
  return undefined;
388
377
  }
@@ -390,8 +379,15 @@ export function toNavigationLink(
390
379
  if (navigationItem.type === 'doc') {
391
380
  return toDocNavigationLink(getDocById(navigationItem.id));
392
381
  } else if (navigationItem.type === 'category') {
393
- return handleCategory(navigationItem);
394
- } else {
395
- throw new Error('unexpected navigation item');
382
+ if (navigationItem.link.type === 'doc') {
383
+ return toDocNavigationLink(getDocById(navigationItem.link.id));
384
+ } else if (navigationItem.link.type === 'generated-index') {
385
+ return {
386
+ title: navigationItem.label,
387
+ permalink: navigationItem.link.permalink,
388
+ };
389
+ }
390
+ throw new Error('unexpected category link type');
396
391
  }
392
+ throw new Error('unexpected navigation item');
397
393
  }
@@ -23,7 +23,8 @@ import {isCategoriesShorthand} from './utils';
23
23
  import type {CategoryMetadataFile} from './generator';
24
24
 
25
25
  // NOTE: we don't add any default values during validation on purpose!
26
- // Config types are exposed to users for typechecking and we use the same type in normalization
26
+ // Config types are exposed to users for typechecking and we use the same type
27
+ // in normalization
27
28
 
28
29
  const sidebarItemBaseSchema = Joi.object<SidebarItemBase>({
29
30
  className: Joi.string(),
@@ -71,7 +72,8 @@ const sidebarItemCategoryLinkSchema = Joi.object<SidebarItemCategoryLink>()
71
72
  then: Joi.object<SidebarItemCategoryLinkGeneratedIndex>({
72
73
  type: 'generated-index',
73
74
  slug: Joi.string().optional(),
74
- // permalink: Joi.string().optional(), // No, this one is not in the user config, only in the normalized version
75
+ // This one is not in the user config, only in the normalized version
76
+ // permalink: Joi.string().optional(),
75
77
  title: Joi.string().optional(),
76
78
  description: Joi.string().optional(),
77
79
  image: Joi.string().optional(),
@@ -132,7 +134,8 @@ function validateSidebarItem(item: unknown): asserts item is SidebarItemConfig {
132
134
  return;
133
135
  }
134
136
  // TODO: remove once with proper Joi support
135
- // Because we can't use Joi to validate nested items (see above), we do it manually
137
+ // Because we can't use Joi to validate nested items (see above), we do it
138
+ // manually
136
139
  if (isCategoriesShorthand(item as SidebarItemConfig)) {
137
140
  Object.values(item as SidebarCategoriesShorthand).forEach((category) =>
138
141
  category.forEach(validateSidebarItem),
package/src/slug.ts CHANGED
@@ -48,17 +48,16 @@ export default function getSlug({
48
48
  function computeSlug(): string {
49
49
  if (frontMatterSlug?.startsWith('/')) {
50
50
  return frontMatterSlug;
51
- } else {
52
- const dirNameSlug = getDirNameSlug();
53
- if (
54
- !frontMatterSlug &&
55
- isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
56
- ) {
57
- return dirNameSlug;
58
- }
59
- const baseSlug = frontMatterSlug || baseID;
60
- return resolvePathname(baseSlug, getDirNameSlug());
61
51
  }
52
+ const dirNameSlug = getDirNameSlug();
53
+ if (
54
+ !frontMatterSlug &&
55
+ isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
56
+ ) {
57
+ return dirNameSlug;
58
+ }
59
+ const baseSlug = frontMatterSlug || baseID;
60
+ return resolvePathname(baseSlug, getDirNameSlug());
62
61
  }
63
62
 
64
63
  function ensureValidSlug(slug: string): string {