@docusaurus/plugin-content-docs 0.0.0-4996 → 0.0.0-4997

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.
@@ -9,8 +9,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.postProcessSidebars = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const utils_1 = require("@docusaurus/utils");
12
+ const docs_1 = require("../docs");
12
13
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
13
14
  function normalizeCategoryLink(category, params) {
15
+ if (category.link?.type === 'doc' && params.draftIds.has(category.link.id)) {
16
+ return undefined;
17
+ }
14
18
  if (category.link?.type === 'generated-index') {
15
19
  // Default slug logic can be improved
16
20
  const getDefaultSlug = () => `/category/${params.categoryLabelSlugger.slug(category.label)}`;
@@ -26,30 +30,35 @@ function normalizeCategoryLink(category, params) {
26
30
  }
27
31
  function postProcessSidebarItem(item, params) {
28
32
  if (item.type === 'category') {
33
+ // Fail-fast if there's actually no subitems, no because all subitems are
34
+ // drafts. This is likely a configuration mistake.
35
+ if (item.items.length === 0 && !item.link) {
36
+ throw new Error(`Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`);
37
+ }
29
38
  const category = {
30
39
  ...item,
31
40
  collapsed: item.collapsed ?? params.sidebarOptions.sidebarCollapsed,
32
41
  collapsible: item.collapsible ?? params.sidebarOptions.sidebarCollapsible,
33
42
  link: normalizeCategoryLink(item, params),
34
- items: item.items.map((subItem) => postProcessSidebarItem(subItem, params)),
43
+ items: item.items
44
+ .map((subItem) => postProcessSidebarItem(subItem, params))
45
+ .filter((v) => Boolean(v)),
35
46
  };
36
47
  // If the current category doesn't have subitems, we render a normal link
37
48
  // instead.
38
49
  if (category.items.length === 0) {
39
- if (!category.link) {
40
- throw new Error(`Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`);
50
+ // Doesn't make sense to render an empty generated index page, so we
51
+ // filter the entire category out as well.
52
+ if (!category.link ||
53
+ category.link.type === 'generated-index' ||
54
+ params.draftIds.has(category.link.id)) {
55
+ return null;
41
56
  }
42
- return category.link.type === 'doc'
43
- ? {
44
- type: 'doc',
45
- label: category.label,
46
- id: category.link.id,
47
- }
48
- : {
49
- type: 'link',
50
- label: category.label,
51
- href: category.link.permalink,
52
- };
57
+ return {
58
+ type: 'doc',
59
+ label: category.label,
60
+ id: category.link.id,
61
+ };
53
62
  }
54
63
  // A non-collapsible category can't be collapsed!
55
64
  if (category.collapsible === false) {
@@ -57,9 +66,16 @@ function postProcessSidebarItem(item, params) {
57
66
  }
58
67
  return category;
59
68
  }
69
+ if ((item.type === 'doc' || item.type === 'ref') &&
70
+ params.draftIds.has(item.id)) {
71
+ return null;
72
+ }
60
73
  return item;
61
74
  }
62
75
  function postProcessSidebars(sidebars, params) {
63
- return lodash_1.default.mapValues(sidebars, (sidebar) => sidebar.map((item) => postProcessSidebarItem(item, params)));
76
+ const draftIds = new Set(params.drafts.flatMap(docs_1.getDocIds));
77
+ return lodash_1.default.mapValues(sidebars, (sidebar) => sidebar
78
+ .map((item) => postProcessSidebarItem(item, { ...params, draftIds }))
79
+ .filter((v) => Boolean(v)));
64
80
  }
65
81
  exports.postProcessSidebars = postProcessSidebars;
@@ -30,7 +30,7 @@ function toSidebarItemsGeneratorVersion(version) {
30
30
  // Handle the generation of autogenerated sidebar items and other
31
31
  // post-processing checks
32
32
  async function processSidebar(unprocessedSidebar, categoriesMetadata, params) {
33
- const { sidebarItemsGenerator, numberPrefixParser, docs, drafts, version } = params;
33
+ const { sidebarItemsGenerator, numberPrefixParser, docs, version } = params;
34
34
  // Just a minor lazy transformation optimization
35
35
  const getSidebarItemsGeneratorDocsAndVersion = lodash_1.default.memoize(() => ({
36
36
  docs: docs.map(toSidebarItemsGeneratorDoc),
@@ -51,23 +51,12 @@ async function processSidebar(unprocessedSidebar, categoriesMetadata, params) {
51
51
  // more autogenerated items, or when loop count (e.g. 10) is reached
52
52
  return processItems(generatedItems);
53
53
  }
54
- const draftIds = new Set(drafts.flatMap(docs_1.getDocIds));
55
- const isDraftItem = (item) => {
56
- if (item.type === 'doc' || item.type === 'ref') {
57
- return draftIds.has(item.id);
58
- }
59
- // If a category only contains draft items, it should be filtered entirely.
60
- if (item.type === 'category') {
61
- return item.items.every(isDraftItem);
62
- }
63
- return false;
64
- };
65
54
  async function processItem(item) {
66
55
  if (item.type === 'category') {
67
56
  return [
68
57
  {
69
58
  ...item,
70
- items: await processItems(item.items),
59
+ items: (await Promise.all(item.items.map(processItem))).flat(),
71
60
  },
72
61
  ];
73
62
  }
@@ -77,7 +66,7 @@ async function processSidebar(unprocessedSidebar, categoriesMetadata, params) {
77
66
  return [item];
78
67
  }
79
68
  async function processItems(items) {
80
- return (await Promise.all(items.filter((i) => !isDraftItem(i)).map(processItem))).flat();
69
+ return (await Promise.all(items.map(processItem))).flat();
81
70
  }
82
71
  const processedSidebar = await processItems(unprocessedSidebar);
83
72
  return processedSidebar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-docs",
3
- "version": "0.0.0-4996",
3
+ "version": "0.0.0-4997",
4
4
  "description": "Docs plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "sideEffects": false,
@@ -25,11 +25,11 @@
25
25
  },
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "@docusaurus/core": "0.0.0-4996",
29
- "@docusaurus/logger": "0.0.0-4996",
30
- "@docusaurus/mdx-loader": "0.0.0-4996",
31
- "@docusaurus/utils": "0.0.0-4996",
32
- "@docusaurus/utils-validation": "0.0.0-4996",
28
+ "@docusaurus/core": "0.0.0-4997",
29
+ "@docusaurus/logger": "0.0.0-4997",
30
+ "@docusaurus/mdx-loader": "0.0.0-4997",
31
+ "@docusaurus/utils": "0.0.0-4997",
32
+ "@docusaurus/utils-validation": "0.0.0-4997",
33
33
  "combine-promises": "^1.1.0",
34
34
  "fs-extra": "^10.1.0",
35
35
  "import-fresh": "^3.3.0",
@@ -41,8 +41,8 @@
41
41
  "webpack": "^5.72.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@docusaurus/module-type-aliases": "0.0.0-4996",
45
- "@docusaurus/types": "0.0.0-4996",
44
+ "@docusaurus/module-type-aliases": "0.0.0-4997",
45
+ "@docusaurus/types": "0.0.0-4997",
46
46
  "@types/js-yaml": "^4.0.5",
47
47
  "@types/picomatch": "^2.3.0",
48
48
  "commander": "^5.1.0",
@@ -58,5 +58,5 @@
58
58
  "engines": {
59
59
  "node": ">=14"
60
60
  },
61
- "gitHead": "a9b7bc9b63dd9dd26f64b9ee837e94a3202678f3"
61
+ "gitHead": "f3fed88a945da54cc2d17b5d6f463332d1965b1b"
62
62
  }
@@ -6,4 +6,5 @@ This part is very complicated and hard to navigate. Sidebars are loaded through
6
6
  2. **Normalization**. The shorthands are expanded. This step is very lenient about the sidebars' shapes. Returns `NormalizedSidebars`.
7
7
  3. **Validation**. The normalized sidebars are validated. This step happens after normalization, because the normalized sidebars are easier to validate, and allows us to repeatedly validate & generate in the future.
8
8
  4. **Generation**. This step is done through the "processor" (naming is hard). The `autogenerated` items are unwrapped. In the future, steps 3 and 4 may be repeatedly done until all autogenerated items are unwrapped. Returns `ProcessedSidebars`.
9
+ - **Important**: this step should only care about unwrapping autogenerated items, not filtering them, writing additional metadata, applying defaults, etc.—everything will be handled in the post-processor. Important because the generator is exposed to the end-user and we want it to be easy to be reasoned about.
9
10
  5. **Post-processing**. Defaults are applied (collapsed states), category links are resolved, empty categories are flattened. Returns `Sidebars`.
@@ -15,12 +15,20 @@ import type {
15
15
  ProcessedSidebars,
16
16
  SidebarItemCategoryLink,
17
17
  } from './types';
18
+ import {getDocIds} from '../docs';
18
19
  import _ from 'lodash';
19
20
 
21
+ type SidebarPostProcessorParams = SidebarProcessorParams & {
22
+ draftIds: Set<string>;
23
+ };
24
+
20
25
  function normalizeCategoryLink(
21
26
  category: ProcessedSidebarItemCategory,
22
- params: SidebarProcessorParams,
27
+ params: SidebarPostProcessorParams,
23
28
  ): SidebarItemCategoryLink | undefined {
29
+ if (category.link?.type === 'doc' && params.draftIds.has(category.link.id)) {
30
+ return undefined;
31
+ }
24
32
  if (category.link?.type === 'generated-index') {
25
33
  // Default slug logic can be improved
26
34
  const getDefaultSlug = () =>
@@ -38,37 +46,42 @@ function normalizeCategoryLink(
38
46
 
39
47
  function postProcessSidebarItem(
40
48
  item: ProcessedSidebarItem,
41
- params: SidebarProcessorParams,
42
- ): SidebarItem {
49
+ params: SidebarPostProcessorParams,
50
+ ): SidebarItem | null {
43
51
  if (item.type === 'category') {
52
+ // Fail-fast if there's actually no subitems, no because all subitems are
53
+ // drafts. This is likely a configuration mistake.
54
+ if (item.items.length === 0 && !item.link) {
55
+ throw new Error(
56
+ `Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`,
57
+ );
58
+ }
44
59
  const category = {
45
60
  ...item,
46
61
  collapsed: item.collapsed ?? params.sidebarOptions.sidebarCollapsed,
47
62
  collapsible: item.collapsible ?? params.sidebarOptions.sidebarCollapsible,
48
63
  link: normalizeCategoryLink(item, params),
49
- items: item.items.map((subItem) =>
50
- postProcessSidebarItem(subItem, params),
51
- ),
64
+ items: item.items
65
+ .map((subItem) => postProcessSidebarItem(subItem, params))
66
+ .filter((v): v is SidebarItem => Boolean(v)),
52
67
  };
53
68
  // If the current category doesn't have subitems, we render a normal link
54
69
  // instead.
55
70
  if (category.items.length === 0) {
56
- if (!category.link) {
57
- throw new Error(
58
- `Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`,
59
- );
71
+ // Doesn't make sense to render an empty generated index page, so we
72
+ // filter the entire category out as well.
73
+ if (
74
+ !category.link ||
75
+ category.link.type === 'generated-index' ||
76
+ params.draftIds.has(category.link.id)
77
+ ) {
78
+ return null;
60
79
  }
61
- return category.link.type === 'doc'
62
- ? {
63
- type: 'doc',
64
- label: category.label,
65
- id: category.link.id,
66
- }
67
- : {
68
- type: 'link',
69
- label: category.label,
70
- href: category.link.permalink,
71
- };
80
+ return {
81
+ type: 'doc',
82
+ label: category.label,
83
+ id: category.link.id,
84
+ };
72
85
  }
73
86
  // A non-collapsible category can't be collapsed!
74
87
  if (category.collapsible === false) {
@@ -76,6 +89,12 @@ function postProcessSidebarItem(
76
89
  }
77
90
  return category;
78
91
  }
92
+ if (
93
+ (item.type === 'doc' || item.type === 'ref') &&
94
+ params.draftIds.has(item.id)
95
+ ) {
96
+ return null;
97
+ }
79
98
  return item;
80
99
  }
81
100
 
@@ -83,7 +102,11 @@ export function postProcessSidebars(
83
102
  sidebars: ProcessedSidebars,
84
103
  params: SidebarProcessorParams,
85
104
  ): Sidebars {
105
+ const draftIds = new Set(params.drafts.flatMap(getDocIds));
106
+
86
107
  return _.mapValues(sidebars, (sidebar) =>
87
- sidebar.map((item) => postProcessSidebarItem(item, params)),
108
+ sidebar
109
+ .map((item) => postProcessSidebarItem(item, {...params, draftIds}))
110
+ .filter((v): v is SidebarItem => Boolean(v)),
88
111
  );
89
112
  }
@@ -26,7 +26,7 @@ import {DefaultSidebarItemsGenerator} from './generator';
26
26
  import {validateSidebars} from './validation';
27
27
  import _ from 'lodash';
28
28
  import combinePromises from 'combine-promises';
29
- import {getDocIds, isCategoryIndex} from '../docs';
29
+ import {isCategoryIndex} from '../docs';
30
30
 
31
31
  function toSidebarItemsGeneratorDoc(
32
32
  doc: DocMetadataBase,
@@ -55,8 +55,7 @@ async function processSidebar(
55
55
  categoriesMetadata: {[filePath: string]: CategoryMetadataFile},
56
56
  params: SidebarProcessorParams,
57
57
  ): Promise<ProcessedSidebar> {
58
- const {sidebarItemsGenerator, numberPrefixParser, docs, drafts, version} =
59
- params;
58
+ const {sidebarItemsGenerator, numberPrefixParser, docs, version} = params;
60
59
 
61
60
  // Just a minor lazy transformation optimization
62
61
  const getSidebarItemsGeneratorDocsAndVersion = _.memoize(() => ({
@@ -82,19 +81,6 @@ async function processSidebar(
82
81
  return processItems(generatedItems);
83
82
  }
84
83
 
85
- const draftIds = new Set(drafts.flatMap(getDocIds));
86
-
87
- const isDraftItem = (item: NormalizedSidebarItem): boolean => {
88
- if (item.type === 'doc' || item.type === 'ref') {
89
- return draftIds.has(item.id);
90
- }
91
- // If a category only contains draft items, it should be filtered entirely.
92
- if (item.type === 'category') {
93
- return item.items.every(isDraftItem);
94
- }
95
- return false;
96
- };
97
-
98
84
  async function processItem(
99
85
  item: NormalizedSidebarItem,
100
86
  ): Promise<ProcessedSidebarItem[]> {
@@ -102,7 +88,7 @@ async function processSidebar(
102
88
  return [
103
89
  {
104
90
  ...item,
105
- items: await processItems(item.items),
91
+ items: (await Promise.all(item.items.map(processItem))).flat(),
106
92
  },
107
93
  ];
108
94
  }
@@ -115,9 +101,7 @@ async function processSidebar(
115
101
  async function processItems(
116
102
  items: NormalizedSidebarItem[],
117
103
  ): Promise<ProcessedSidebarItem[]> {
118
- return (
119
- await Promise.all(items.filter((i) => !isDraftItem(i)).map(processItem))
120
- ).flat();
104
+ return (await Promise.all(items.map(processItem))).flat();
121
105
  }
122
106
 
123
107
  const processedSidebar = await processItems(unprocessedSidebar);