@docusaurus/plugin-content-docs 2.0.0-beta.1 → 2.0.0-beta.10

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 (140) 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 +1 -4
  7. package/lib/client/docsClientUtils.js +21 -31
  8. package/lib/docFrontMatter.d.ts +1 -1
  9. package/lib/docFrontMatter.js +10 -6
  10. package/lib/docs.d.ts +25 -3
  11. package/lib/docs.js +125 -38
  12. package/lib/globalData.d.ts +1 -1
  13. package/lib/index.d.ts +1 -1
  14. package/lib/index.js +104 -138
  15. package/lib/lastUpdate.js +9 -10
  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 +49 -17
  22. package/lib/props.d.ts +7 -2
  23. package/lib/props.js +61 -9
  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 +24 -21
  45. package/lib/translations.d.ts +2 -2
  46. package/lib/translations.js +71 -29
  47. package/lib/types.d.ts +52 -62
  48. package/lib/versions.d.ts +3 -3
  49. package/lib/versions.js +76 -24
  50. package/package.json +22 -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 +753 -112
  75. package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -18
  76. package/src/__tests__/cli.test.ts +15 -11
  77. package/src/__tests__/docFrontMatter.test.ts +195 -40
  78. package/src/__tests__/docs.test.ts +311 -150
  79. package/src/__tests__/index.test.ts +112 -69
  80. package/src/__tests__/lastUpdate.test.ts +3 -2
  81. package/src/__tests__/options.test.ts +48 -4
  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 -2
  85. package/src/__tests__/versions.test.ts +93 -67
  86. package/src/categoryGeneratedIndex.ts +57 -0
  87. package/src/cli.ts +8 -41
  88. package/src/client/__tests__/docsClientUtils.test.ts +4 -5
  89. package/src/client/docsClientUtils.ts +19 -41
  90. package/{types.d.ts → src/deps.d.ts} +0 -0
  91. package/src/docFrontMatter.ts +13 -7
  92. package/src/docs.ts +158 -29
  93. package/src/globalData.ts +6 -1
  94. package/src/index.ts +134 -179
  95. package/src/lastUpdate.ts +10 -9
  96. package/src/markdown/index.ts +8 -12
  97. package/src/numberPrefix.ts +5 -3
  98. package/src/options.ts +59 -28
  99. package/src/plugin-content-docs.d.ts +179 -35
  100. package/src/props.ts +91 -16
  101. package/src/routes.ts +173 -0
  102. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  103. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  104. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  105. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  106. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  107. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  108. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  109. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  110. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  111. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  112. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  113. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  114. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  115. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  116. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +36 -6
  117. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +143 -18
  118. package/src/sidebars/__tests__/index.test.ts +204 -0
  119. package/src/sidebars/__tests__/processor.test.ts +237 -0
  120. package/src/sidebars/__tests__/utils.test.ts +695 -0
  121. package/src/sidebars/__tests__/validation.test.ts +105 -0
  122. package/src/sidebars/generator.ts +310 -0
  123. package/src/sidebars/index.ts +94 -0
  124. package/src/sidebars/normalization.ts +112 -0
  125. package/src/sidebars/processor.ts +154 -0
  126. package/src/sidebars/types.ts +211 -0
  127. package/src/sidebars/utils.ts +329 -0
  128. package/src/sidebars/validation.ts +168 -0
  129. package/src/slug.ts +32 -17
  130. package/src/tags.ts +19 -0
  131. package/src/theme/hooks/useDocs.ts +5 -1
  132. package/src/translations.ts +103 -47
  133. package/src/types.ts +67 -105
  134. package/src/versions.ts +117 -21
  135. package/lib/sidebarItemsGenerator.js +0 -211
  136. package/lib/sidebars.d.ts +0 -43
  137. package/lib/sidebars.js +0 -319
  138. package/src/__tests__/sidebars.test.ts +0 -639
  139. package/src/sidebarItemsGenerator.ts +0 -307
  140. package/src/sidebars.ts +0 -506
package/lib/index.js CHANGED
@@ -8,29 +8,31 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.validateOptions = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const path_1 = tslib_1.__importDefault(require("path"));
12
- const constants_1 = require("@docusaurus/core/lib/constants");
11
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
13
12
  const utils_1 = require("@docusaurus/utils");
14
13
  const sidebars_1 = require("./sidebars");
14
+ const generator_1 = require("./sidebars/generator");
15
15
  const docs_1 = require("./docs");
16
16
  const versions_1 = require("./versions");
17
17
  const cli_1 = require("./cli");
18
- const constants_2 = require("./constants");
18
+ const constants_1 = require("./constants");
19
19
  const lodash_1 = require("lodash");
20
20
  const globalData_1 = require("./globalData");
21
21
  const props_1 = require("./props");
22
22
  const translations_1 = require("./translations");
23
- const sidebarItemsGenerator_1 = require("./sidebarItemsGenerator");
24
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
23
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
24
+ const tags_1 = require("./tags");
25
+ const routes_1 = require("./routes");
26
+ const utils_2 = require("./sidebars/utils");
27
+ const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
25
28
  function pluginContentDocs(context, options) {
26
29
  var _a;
27
30
  const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
28
- const versionsMetadata = versions_1.readVersionsMetadata({ context, options });
29
- const sourceToPermalink = {};
30
- const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_PLUGIN_ID;
31
+ const versionsMetadata = (0, versions_1.readVersionsMetadata)({ context, options });
32
+ const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : utils_1.DEFAULT_PLUGIN_ID;
31
33
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-docs');
32
34
  const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
33
- const aliasedSource = (source) => `~docs/${utils_1.posixPath(path_1.default.relative(pluginDataDirRoot, source))}`;
35
+ const aliasedSource = (source) => `~docs/${(0, utils_1.posixPath)(path_1.default.relative(pluginDataDirRoot, source))}`;
34
36
  return {
35
37
  name: 'docusaurus-plugin-content-docs',
36
38
  getThemePath() {
@@ -40,7 +42,7 @@ function pluginContentDocs(context, options) {
40
42
  return path_1.default.resolve(__dirname, '..', 'src', 'theme');
41
43
  },
42
44
  extendCli(cli) {
43
- const isDefaultPluginId = pluginId === constants_1.DEFAULT_PLUGIN_ID;
45
+ const isDefaultPluginId = pluginId === utils_1.DEFAULT_PLUGIN_ID;
44
46
  // Need to create one distinct command per plugin instance
45
47
  // otherwise 2 instances would try to execute the command!
46
48
  const command = isDefaultPluginId
@@ -54,43 +56,38 @@ function pluginContentDocs(context, options) {
54
56
  .arguments('<version>')
55
57
  .description(commandDescription)
56
58
  .action((version) => {
57
- cli_1.cliDocsVersionCommand(version, siteDir, pluginId, {
59
+ (0, cli_1.cliDocsVersionCommand)(version, siteDir, pluginId, {
58
60
  path: options.path,
59
61
  sidebarPath: options.sidebarPath,
62
+ sidebarCollapsed: options.sidebarCollapsed,
63
+ sidebarCollapsible: options.sidebarCollapsible,
60
64
  });
61
65
  });
62
66
  },
63
67
  async getTranslationFiles({ content }) {
64
- return translations_1.getLoadedContentTranslationFiles(content);
65
- },
66
- getClientModules() {
67
- const modules = [];
68
- if (options.admonitions) {
69
- modules.push(require.resolve('remark-admonitions/styles/infima.css'));
70
- }
71
- return modules;
68
+ return (0, translations_1.getLoadedContentTranslationFiles)(content);
72
69
  },
73
70
  getPathsToWatch() {
74
71
  function getVersionPathsToWatch(version) {
75
72
  const result = [
76
- ...lodash_1.flatten(options.include.map((pattern) => versions_1.getDocsDirPaths(version).map((docsDirPath) => `${docsDirPath}/${pattern}`))),
77
- `${version.contentPath}/**/${sidebarItemsGenerator_1.CategoryMetadataFilenamePattern}`,
73
+ ...options.include.flatMap((pattern) => (0, versions_1.getDocsDirPaths)(version).map((docsDirPath) => `${docsDirPath}/${pattern}`)),
74
+ `${version.contentPath}/**/${generator_1.CategoryMetadataFilenamePattern}`,
78
75
  ];
79
76
  if (typeof version.sidebarFilePath === 'string') {
80
77
  result.unshift(version.sidebarFilePath);
81
78
  }
82
79
  return result;
83
80
  }
84
- return lodash_1.flatten(versionsMetadata.map(getVersionPathsToWatch));
81
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
85
82
  },
86
83
  async loadContent() {
87
84
  async function loadVersionDocsBase(versionMetadata) {
88
- const docFiles = await docs_1.readVersionDocs(versionMetadata, options);
85
+ const docFiles = await (0, docs_1.readVersionDocs)(versionMetadata, options);
89
86
  if (docFiles.length === 0) {
90
87
  throw new Error(`Docs version "${versionMetadata.versionName}" has no docs! At least one doc should exist at "${path_1.default.relative(siteDir, versionMetadata.contentPath)}".`);
91
88
  }
92
89
  async function processVersionDoc(docFile) {
93
- return docs_1.processDocMetadata({
90
+ return (0, docs_1.processDocMetadata)({
94
91
  docFile,
95
92
  versionMetadata,
96
93
  context,
@@ -100,76 +97,28 @@ function pluginContentDocs(context, options) {
100
97
  return Promise.all(docFiles.map(processVersionDoc));
101
98
  }
102
99
  async function doLoadVersion(versionMetadata) {
103
- const unprocessedSidebars = sidebars_1.loadSidebars(versionMetadata.sidebarFilePath);
104
- const docsBase = await loadVersionDocsBase(versionMetadata);
105
- const docsBaseById = lodash_1.keyBy(docsBase, (doc) => doc.id);
106
- const sidebars = await sidebars_1.processSidebars({
100
+ const docs = await loadVersionDocsBase(versionMetadata);
101
+ const sidebars = await (0, sidebars_1.loadSidebars)(versionMetadata.sidebarFilePath, {
107
102
  sidebarItemsGenerator: options.sidebarItemsGenerator,
108
103
  numberPrefixParser: options.numberPrefixParser,
109
- unprocessedSidebars,
110
- docs: docsBase,
104
+ docs,
111
105
  version: versionMetadata,
106
+ sidebarOptions: {
107
+ sidebarCollapsed: options.sidebarCollapsed,
108
+ sidebarCollapsible: options.sidebarCollapsible,
109
+ },
110
+ categoryLabelSlugger: (0, utils_1.createSlugger)(),
112
111
  });
113
- const sidebarsUtils = sidebars_1.createSidebarsUtils(sidebars);
114
- const validDocIds = Object.keys(docsBaseById);
115
- sidebarsUtils.checkSidebarsDocIds(validDocIds, versionMetadata.sidebarFilePath);
116
- // Add sidebar/next/previous to the docs
117
- function addNavData(doc) {
118
- const { sidebarName, previousId, nextId, } = sidebarsUtils.getDocNavigation(doc.id);
119
- const toDocNavLink = (navDocId) => {
120
- var _a, _b;
121
- const { title, permalink, frontMatter } = docsBaseById[navDocId];
122
- return {
123
- title: (_b = (_a = frontMatter.pagination_label) !== null && _a !== void 0 ? _a : frontMatter.sidebar_label) !== null && _b !== void 0 ? _b : title,
124
- permalink,
125
- };
126
- };
127
- return {
128
- ...doc,
129
- sidebar: sidebarName,
130
- previous: previousId ? toDocNavLink(previousId) : undefined,
131
- next: nextId ? toDocNavLink(nextId) : undefined,
132
- };
133
- }
134
- const docs = docsBase.map(addNavData);
135
- // sort to ensure consistent output for tests
136
- docs.sort((a, b) => a.id.localeCompare(b.id));
137
- // TODO annoying side effect!
138
- Object.values(docs).forEach((loadedDoc) => {
139
- const { source, permalink } = loadedDoc;
140
- sourceToPermalink[source] = permalink;
141
- });
142
- // TODO really useful? replace with global state logic?
143
- const permalinkToSidebar = {};
144
- Object.values(docs).forEach((doc) => {
145
- if (doc.sidebar) {
146
- permalinkToSidebar[doc.permalink] = doc.sidebar;
147
- }
148
- });
149
- // The "main doc" is the "version entry point"
150
- // We browse this doc by clicking on a version:
151
- // - the "home" doc (at '/docs/')
152
- // - the first doc of the first sidebar
153
- // - a random doc (if no docs are in any sidebar... edge case)
154
- function getMainDoc() {
155
- const versionHomeDoc = docs.find((doc) => doc.unversionedId === options.homePageId || doc.slug === '/');
156
- const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
157
- if (versionHomeDoc) {
158
- return versionHomeDoc;
159
- }
160
- else if (firstDocIdOfFirstSidebar) {
161
- return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar);
162
- }
163
- else {
164
- return docs[0];
165
- }
166
- }
112
+ const sidebarsUtils = (0, utils_2.createSidebarsUtils)(sidebars);
167
113
  return {
168
114
  ...versionMetadata,
169
- mainDocId: getMainDoc().unversionedId,
115
+ docs: (0, docs_1.addDocNavigation)(docs, sidebarsUtils, versionMetadata.sidebarFilePath),
170
116
  sidebars,
171
- permalinkToSidebar,
172
- docs: docs.map(addNavData),
117
+ mainDocId: (0, docs_1.getMainDocId)({ docs, sidebarsUtils }),
118
+ categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
119
+ docs,
120
+ sidebarsUtils,
121
+ }),
173
122
  };
174
123
  }
175
124
  async function loadVersion(versionMetadata) {
@@ -186,81 +135,96 @@ function pluginContentDocs(context, options) {
186
135
  };
187
136
  },
188
137
  translateContent({ content, translationFiles }) {
189
- return translations_1.translateLoadedContent(content, translationFiles);
138
+ return (0, translations_1.translateLoadedContent)(content, translationFiles);
190
139
  },
191
140
  async contentLoaded({ content, actions }) {
192
141
  const { loadedVersions } = content;
193
- const { docLayoutComponent, docItemComponent } = options;
142
+ const { docLayoutComponent, docItemComponent, docCategoryGeneratedIndexComponent, } = options;
194
143
  const { addRoute, createData, setGlobalData } = actions;
195
- const createDocRoutes = async (docs) => {
196
- const routes = await Promise.all(docs.map(async (metadataItem) => {
197
- await createData(
198
- // Note that this created data path must be in sync with
199
- // metadataPath provided to mdx-loader.
200
- `${utils_1.docuHash(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
201
- return {
202
- path: metadataItem.permalink,
203
- component: docItemComponent,
144
+ async function createVersionTagsRoutes(version) {
145
+ const versionTags = (0, tags_1.getVersionTags)(version.docs);
146
+ // TODO tags should be a sub route of the version route
147
+ async function createTagsListPage() {
148
+ const tagsProp = Object.values(versionTags).map((tagValue) => ({
149
+ name: tagValue.name,
150
+ permalink: tagValue.permalink,
151
+ count: tagValue.docIds.length,
152
+ }));
153
+ // Only create /tags page if there are tags.
154
+ if (Object.keys(tagsProp).length > 0) {
155
+ const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`tags-list-${version.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
156
+ addRoute({
157
+ path: version.tagsPath,
158
+ exact: true,
159
+ component: options.docTagsListComponent,
160
+ modules: {
161
+ tags: aliasedSource(tagsPropPath),
162
+ },
163
+ });
164
+ }
165
+ }
166
+ // TODO tags should be a sub route of the version route
167
+ async function createTagDocListPage(tag) {
168
+ const tagProps = (0, props_1.toTagDocListProp)({
169
+ allTagsPath: version.tagsPath,
170
+ tag,
171
+ docs: version.docs,
172
+ });
173
+ const tagPropPath = await createData(`${(0, utils_1.docuHash)(`tag-${tag.permalink}`)}.json`, JSON.stringify(tagProps, null, 2));
174
+ addRoute({
175
+ path: tag.permalink,
176
+ component: options.docTagDocListComponent,
204
177
  exact: true,
205
178
  modules: {
206
- content: metadataItem.source,
179
+ tag: aliasedSource(tagPropPath),
207
180
  },
208
- };
209
- }));
210
- return routes.sort((a, b) => a.path.localeCompare(b.path));
211
- };
212
- async function doCreateVersionRoutes(loadedVersion) {
213
- const versionMetadataPropPath = await createData(`${utils_1.docuHash(`version-${loadedVersion.versionName}-metadata-prop`)}.json`, JSON.stringify(props_1.toVersionMetadataProp(pluginId, loadedVersion), null, 2));
214
- addRoute({
215
- path: loadedVersion.versionPath,
216
- // allow matching /docs/* as well
217
- exact: false,
218
- // main docs component (DocPage)
219
- component: docLayoutComponent,
220
- // sub-routes for each doc
221
- routes: await createDocRoutes(loadedVersion.docs),
222
- modules: {
223
- versionMetadata: aliasedSource(versionMetadataPropPath),
224
- },
225
- priority: loadedVersion.routePriority,
226
- });
227
- }
228
- async function createVersionRoutes(loadedVersion) {
229
- try {
230
- return await doCreateVersionRoutes(loadedVersion);
231
- }
232
- catch (e) {
233
- console.error(chalk_1.default.red(`Can't create version routes for version "${loadedVersion.versionName}"`));
234
- throw e;
181
+ });
235
182
  }
183
+ await createTagsListPage();
184
+ await Promise.all(Object.values(versionTags).map(createTagDocListPage));
236
185
  }
237
- await Promise.all(loadedVersions.map(createVersionRoutes));
186
+ await Promise.all(loadedVersions.map((loadedVersion) => (0, routes_1.createVersionRoutes)({
187
+ loadedVersion,
188
+ docItemComponent,
189
+ docLayoutComponent,
190
+ docCategoryGeneratedIndexComponent,
191
+ pluginId,
192
+ aliasedSource,
193
+ actions,
194
+ })));
195
+ // TODO tags should be a sub route of the version route
196
+ await Promise.all(loadedVersions.map(createVersionTagsRoutes));
238
197
  setGlobalData({
239
- path: utils_1.normalizeUrl([baseUrl, options.routeBasePath]),
198
+ path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
240
199
  versions: loadedVersions.map(globalData_1.toGlobalDataVersion),
241
200
  });
242
201
  },
243
- configureWebpack(_config, isServer, utils) {
202
+ configureWebpack(_config, isServer, utils, content) {
244
203
  const { getJSLoader } = utils;
245
204
  const { rehypePlugins, remarkPlugins, beforeDefaultRehypePlugins, beforeDefaultRemarkPlugins, } = options;
205
+ function getSourceToPermalink() {
206
+ const allDocs = content.loadedVersions.flatMap((v) => v.docs);
207
+ return (0, lodash_1.mapValues)((0, lodash_1.keyBy)(allDocs, (d) => d.source), (d) => d.permalink);
208
+ }
246
209
  const docsMarkdownOptions = {
247
210
  siteDir,
248
- sourceToPermalink,
211
+ sourceToPermalink: getSourceToPermalink(),
249
212
  versionsMetadata,
250
213
  onBrokenMarkdownLink: (brokenMarkdownLink) => {
251
214
  if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
252
215
  return;
253
216
  }
254
- utils_1.reportMessage(`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.contentPaths.versionName}`, siteConfig.onBrokenMarkdownLinks);
217
+ (0, utils_1.reportMessage)(`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.contentPaths.versionName}`, siteConfig.onBrokenMarkdownLinks);
255
218
  },
256
219
  };
257
220
  function createMDXLoaderRule() {
221
+ const contentDirs = versionsMetadata.flatMap(versions_1.getDocsDirPaths);
258
222
  return {
259
223
  test: /(\.mdx?)$/,
260
- include: lodash_1.flatten(versionsMetadata.map(versions_1.getDocsDirPaths))
224
+ include: contentDirs
261
225
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
262
226
  .map(utils_1.addTrailingPathSeparator),
263
- use: lodash_1.compact([
227
+ use: [
264
228
  getJSLoader({ isServer }),
265
229
  {
266
230
  loader: require.resolve('@docusaurus/mdx-loader'),
@@ -269,12 +233,14 @@ function pluginContentDocs(context, options) {
269
233
  rehypePlugins,
270
234
  beforeDefaultRehypePlugins,
271
235
  beforeDefaultRemarkPlugins,
272
- staticDir: path_1.default.join(siteDir, constants_1.STATIC_DIR_NAME),
236
+ staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
237
+ siteDir,
238
+ isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
273
239
  metadataPath: (mdxPath) => {
274
240
  // Note that metadataPath must be the same/in-sync as
275
241
  // the path from createData for each MDX.
276
- const aliasedPath = utils_1.aliasedSitePath(mdxPath, siteDir);
277
- return path_1.default.join(dataDir, `${utils_1.docuHash(aliasedPath)}.json`);
242
+ const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
243
+ return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
278
244
  },
279
245
  },
280
246
  },
@@ -282,14 +248,14 @@ function pluginContentDocs(context, options) {
282
248
  loader: path_1.default.resolve(__dirname, './markdown/index.js'),
283
249
  options: docsMarkdownOptions,
284
250
  },
285
- ]),
251
+ ].filter(Boolean),
286
252
  };
287
253
  }
288
254
  return {
289
255
  ignoreWarnings: [
290
256
  // Suppress warnings about non-existing of versions file.
291
257
  (e) => e.message.includes("Can't resolve") &&
292
- e.message.includes(constants_2.VERSIONS_JSON_FILE),
258
+ e.message.includes(constants_1.VERSIONS_JSON_FILE),
293
259
  ],
294
260
  resolve: {
295
261
  alias: {
package/lib/lastUpdate.js CHANGED
@@ -8,9 +8,8 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.getFileLastUpdate = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const shelljs_1 = tslib_1.__importDefault(require("shelljs"));
12
- const execa_1 = tslib_1.__importDefault(require("execa"));
13
- const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+), (.+)$/;
11
+ const shelljs_1 = (0, tslib_1.__importDefault)(require("shelljs"));
12
+ const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+),(.+)$/;
14
13
  let showedGitRequirementError = false;
15
14
  async function getFileLastUpdate(filePath) {
16
15
  if (!filePath) {
@@ -35,13 +34,13 @@ async function getFileLastUpdate(filePath) {
35
34
  }
36
35
  return null;
37
36
  }
38
- const { stdout } = await execa_1.default('git', [
39
- 'log',
40
- '-1',
41
- '--format=%ct, %an',
42
- filePath,
43
- ]);
44
- return getTimestampAndAuthor(stdout);
37
+ const result = shelljs_1.default.exec(`git log -1 --format=%ct,%an ${filePath}`, {
38
+ silent: true,
39
+ });
40
+ if (result.code !== 0) {
41
+ throw new Error(`Retrieval of git history failed at ${filePath} with exit code ${result.code}: ${result.stderr}`);
42
+ }
43
+ return getTimestampAndAuthor(result.stdout.trim());
45
44
  }
46
45
  catch (error) {
47
46
  console.error(error);
@@ -4,9 +4,6 @@
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
- /// <reference types="node" />
8
- interface Loader extends Function {
9
- (this: any, source: string): string | Buffer | void | undefined;
10
- }
11
- declare const markdownLoader: Loader;
12
- export default markdownLoader;
7
+ import { DocsMarkdownOption } from '../types';
8
+ import type { LoaderContext } from 'webpack';
9
+ export default function markdownLoader(this: LoaderContext<DocsMarkdownOption>, source: string): void;
@@ -7,10 +7,10 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const linkify_1 = require("./linkify");
10
- const markdownLoader = function (source) {
10
+ function markdownLoader(source) {
11
11
  const fileString = source;
12
12
  const callback = this.async();
13
13
  const options = this.getOptions();
14
- return (callback && callback(null, linkify_1.linkify(fileString, this.resourcePath, options)));
15
- };
14
+ return (callback && callback(null, (0, linkify_1.linkify)(fileString, this.resourcePath, options)));
15
+ }
16
16
  exports.default = markdownLoader;
@@ -10,7 +10,7 @@ exports.linkify = void 0;
10
10
  const versions_1 = require("../versions");
11
11
  const utils_1 = require("@docusaurus/utils");
12
12
  function getVersion(filePath, options) {
13
- const versionFound = options.versionsMetadata.find((version) => versions_1.getDocsDirPaths(version).some((docsDirPath) => filePath.startsWith(docsDirPath)));
13
+ const versionFound = options.versionsMetadata.find((version) => (0, versions_1.getDocsDirPaths)(version).some((docsDirPath) => filePath.startsWith(docsDirPath)));
14
14
  if (!versionFound) {
15
15
  throw new Error(`Unexpected error: Markdown file at "${filePath}" does not belong to any docs version!`);
16
16
  }
@@ -18,7 +18,7 @@ function getVersion(filePath, options) {
18
18
  }
19
19
  function linkify(fileString, filePath, options) {
20
20
  const { siteDir, sourceToPermalink, onBrokenMarkdownLink } = options;
21
- const { newContent, brokenMarkdownLinks } = utils_1.replaceMarkdownLinks({
21
+ const { newContent, brokenMarkdownLinks } = (0, utils_1.replaceMarkdownLinks)({
22
22
  siteDir,
23
23
  fileString,
24
24
  filePath,
@@ -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 { NumberPrefixParser } from './types';
7
+ import type { NumberPrefixParser } from './types';
8
8
  export declare const DefaultNumberPrefixParser: NumberPrefixParser;
9
9
  export declare const DisabledNumberPrefixParser: NumberPrefixParser;
10
10
  export declare function stripNumberPrefix(str: string, parser: NumberPrefixParser): string;
package/lib/options.d.ts CHANGED
@@ -4,9 +4,9 @@
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 { PluginOptions } from './types';
7
+ import type { PluginOptions } from './types';
8
8
  import { Joi } from '@docusaurus/utils-validation';
9
- import { OptionValidationContext, ValidationResult } from '@docusaurus/types';
9
+ import type { OptionValidationContext, ValidationResult } from '@docusaurus/types';
10
10
  export declare const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'>;
11
11
  export declare const OptionsSchema: Joi.ObjectSchema<any>;
12
- export declare function validateOptions({ validate, options, }: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions>;
12
+ export declare function validateOptions({ validate, options: userOptions, }: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions>;
package/lib/options.js CHANGED
@@ -1,21 +1,32 @@
1
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
+ */
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
9
  exports.validateOptions = exports.OptionsSchema = exports.DEFAULT_OPTIONS = void 0;
4
10
  const tslib_1 = require("tslib");
5
11
  const utils_validation_1 = require("@docusaurus/utils-validation");
6
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
- const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
8
- const sidebarItemsGenerator_1 = require("./sidebarItemsGenerator");
12
+ const utils_1 = require("@docusaurus/utils");
13
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
14
+ const remark_admonitions_1 = (0, tslib_1.__importDefault)(require("remark-admonitions"));
15
+ const generator_1 = require("./sidebars/generator");
9
16
  const numberPrefix_1 = require("./numberPrefix");
10
17
  exports.DEFAULT_OPTIONS = {
11
18
  path: 'docs',
12
19
  routeBasePath: 'docs',
13
- homePageId: undefined,
20
+ tagsBasePath: 'tags',
14
21
  include: ['**/*.{md,mdx}'],
15
- sidebarItemsGenerator: sidebarItemsGenerator_1.DefaultSidebarItemsGenerator,
22
+ exclude: utils_1.GlobExcludeDefault,
23
+ sidebarItemsGenerator: generator_1.DefaultSidebarItemsGenerator,
16
24
  numberPrefixParser: numberPrefix_1.DefaultNumberPrefixParser,
17
25
  docLayoutComponent: '@theme/DocPage',
18
26
  docItemComponent: '@theme/DocItem',
27
+ docTagDocListComponent: '@theme/DocTagDocListPage',
28
+ docTagsListComponent: '@theme/DocTagsListPage',
29
+ docCategoryGeneratedIndexComponent: '@theme/DocCategoryGeneratedIndexPage',
19
30
  remarkPlugins: [],
20
31
  rehypePlugins: [],
21
32
  beforeDefaultRemarkPlugins: [],
@@ -23,17 +34,21 @@ exports.DEFAULT_OPTIONS = {
23
34
  showLastUpdateTime: false,
24
35
  showLastUpdateAuthor: false,
25
36
  admonitions: {},
26
- excludeNextVersionDocs: false,
27
37
  includeCurrentVersion: true,
28
38
  disableVersioning: false,
29
39
  lastVersion: undefined,
30
40
  versions: {},
31
41
  editCurrentVersion: false,
32
42
  editLocalizedFiles: false,
43
+ sidebarCollapsible: true,
44
+ sidebarCollapsed: true,
33
45
  };
34
46
  const VersionOptionsSchema = utils_validation_1.Joi.object({
35
47
  path: utils_validation_1.Joi.string().allow('').optional(),
36
48
  label: utils_validation_1.Joi.string().optional(),
49
+ banner: utils_validation_1.Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
50
+ badge: utils_validation_1.Joi.boolean().optional(),
51
+ className: utils_validation_1.Joi.string().optional(),
37
52
  });
38
53
  const VersionsOptionsSchema = utils_validation_1.Joi.object()
39
54
  .pattern(utils_validation_1.Joi.string().required(), VersionOptionsSchema)
@@ -47,10 +62,16 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
47
62
  // '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
48
63
  // .allow('') ""
49
64
  .default(exports.DEFAULT_OPTIONS.routeBasePath),
50
- homePageId: utils_validation_1.Joi.string().optional(),
65
+ tagsBasePath: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.tagsBasePath),
66
+ homePageId: utils_validation_1.Joi.any().forbidden().messages({
67
+ 'any.unknown': 'The docs plugin option homePageId is not supported anymore. To make a doc the "home", please add "slug: /" in its front matter. See: https://docusaurus.io/docs/next/docs-introduction#home-page-docs',
68
+ }),
51
69
  include: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string()).default(exports.DEFAULT_OPTIONS.include),
70
+ exclude: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string()).default(exports.DEFAULT_OPTIONS.exclude),
52
71
  sidebarPath: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.boolean().invalid(true), utils_validation_1.Joi.string()),
53
72
  sidebarItemsGenerator: utils_validation_1.Joi.function().default(() => exports.DEFAULT_OPTIONS.sidebarItemsGenerator),
73
+ sidebarCollapsible: utils_validation_1.Joi.boolean().default(exports.DEFAULT_OPTIONS.sidebarCollapsible),
74
+ sidebarCollapsed: utils_validation_1.Joi.boolean().default(exports.DEFAULT_OPTIONS.sidebarCollapsed),
54
75
  numberPrefixParser: utils_validation_1.Joi.alternatives()
55
76
  .try(utils_validation_1.Joi.function(),
56
77
  // Convert boolean values to functions
@@ -60,6 +81,9 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
60
81
  .default(() => exports.DEFAULT_OPTIONS.numberPrefixParser),
61
82
  docLayoutComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docLayoutComponent),
62
83
  docItemComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docItemComponent),
84
+ docTagsListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagsListComponent),
85
+ docTagDocListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagDocListComponent),
86
+ docCategoryGeneratedIndexComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docCategoryGeneratedIndexComponent),
63
87
  remarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.remarkPlugins),
64
88
  rehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.rehypePlugins),
65
89
  beforeDefaultRemarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.beforeDefaultRemarkPlugins),
@@ -69,22 +93,30 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
69
93
  .default(exports.DEFAULT_OPTIONS.admonitions),
70
94
  showLastUpdateTime: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.showLastUpdateTime),
71
95
  showLastUpdateAuthor: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.showLastUpdateAuthor),
72
- excludeNextVersionDocs: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.excludeNextVersionDocs),
73
96
  includeCurrentVersion: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.includeCurrentVersion),
74
97
  onlyIncludeVersions: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string().required()).optional(),
75
98
  disableVersioning: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.disableVersioning),
76
99
  lastVersion: utils_validation_1.Joi.string().optional(),
77
100
  versions: VersionsOptionsSchema,
78
101
  });
79
- function validateOptions({ validate, options, }) {
80
- // TODO remove homePageId before end of 2020
81
- // "slug: /" is better because the home doc can be different across versions
82
- if (options.homePageId) {
83
- console.log(chalk_1.default.red(`The docs plugin option homePageId=${options.homePageId} is deprecated. To make a doc the "home", prefer frontmatter: "slug: /"`));
84
- }
85
- if (typeof options.excludeNextVersionDocs !== 'undefined') {
86
- console.log(chalk_1.default.red(`The docs plugin option "excludeNextVersionDocs=${options.excludeNextVersionDocs}" is deprecated. Use the "includeCurrentVersion=${!options.excludeNextVersionDocs}" option instead!"`));
87
- options.includeCurrentVersion = !options.excludeNextVersionDocs;
102
+ function validateOptions({ validate, options: userOptions, }) {
103
+ let options = userOptions;
104
+ if (options.sidebarCollapsible === false) {
105
+ // When sidebarCollapsible=false and sidebarCollapsed=undefined, we don't want to have the inconsistency warning
106
+ // We let options.sidebarCollapsible become the default value for options.sidebarCollapsed
107
+ if (typeof options.sidebarCollapsed === 'undefined') {
108
+ options = {
109
+ ...options,
110
+ sidebarCollapsed: false,
111
+ };
112
+ }
113
+ if (options.sidebarCollapsed) {
114
+ console.warn(chalk_1.default.yellow('The docs plugin config is inconsistent. It does not make sense to use sidebarCollapsible=false and sidebarCollapsed=true at the same time. sidebarCollapsed=false will be ignored.'));
115
+ options = {
116
+ ...options,
117
+ sidebarCollapsed: false,
118
+ };
119
+ }
88
120
  }
89
121
  const normalizedOptions = validate(exports.OptionsSchema, options);
90
122
  if (normalizedOptions.admonitions) {
package/lib/props.d.ts CHANGED
@@ -4,7 +4,12 @@
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 { LoadedVersion } from './types';
8
- import { PropSidebars, PropVersionMetadata } from '@docusaurus/plugin-content-docs-types';
7
+ import type { LoadedVersion, VersionTag, DocMetadata } from './types';
8
+ import type { PropSidebars, PropVersionMetadata, PropTagDocList } from '@docusaurus/plugin-content-docs';
9
9
  export declare function toSidebarsProp(loadedVersion: LoadedVersion): PropSidebars;
10
10
  export declare function toVersionMetadataProp(pluginId: string, loadedVersion: LoadedVersion): PropVersionMetadata;
11
+ export declare function toTagDocListProp({ allTagsPath, tag, docs, }: {
12
+ allTagsPath: string;
13
+ tag: VersionTag;
14
+ docs: Pick<DocMetadata, 'id' | 'title' | 'description' | 'permalink'>[];
15
+ }): PropTagDocList;