@docusaurus/plugin-content-docs 2.0.0-beta.8e9b829d9 → 2.0.0-beta.9

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 (103) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/cli.d.ts +1 -1
  3. package/lib/cli.js +18 -23
  4. package/lib/client/docsClientUtils.d.ts +0 -3
  5. package/lib/client/docsClientUtils.js +10 -7
  6. package/lib/docFrontMatter.js +6 -2
  7. package/lib/docs.d.ts +3 -1
  8. package/lib/docs.js +76 -25
  9. package/lib/index.js +70 -77
  10. package/lib/lastUpdate.js +4 -4
  11. package/lib/markdown/index.d.ts +3 -6
  12. package/lib/markdown/index.js +3 -3
  13. package/lib/markdown/linkify.js +2 -2
  14. package/lib/options.js +12 -4
  15. package/lib/props.d.ts +7 -2
  16. package/lib/props.js +26 -3
  17. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +2 -1
  18. package/lib/sidebars/generator.js +174 -0
  19. package/lib/sidebars/index.d.ts +14 -0
  20. package/lib/sidebars/index.js +64 -0
  21. package/lib/sidebars/normalization.d.ts +9 -0
  22. package/lib/sidebars/normalization.js +58 -0
  23. package/lib/sidebars/processor.d.ts +16 -0
  24. package/lib/sidebars/processor.js +70 -0
  25. package/lib/sidebars/types.d.ts +87 -0
  26. package/lib/sidebars/types.js +13 -0
  27. package/lib/sidebars/utils.d.ts +22 -0
  28. package/lib/sidebars/utils.js +101 -0
  29. package/lib/sidebars/validation.d.ts +8 -0
  30. package/lib/sidebars/validation.js +102 -0
  31. package/lib/slug.js +4 -4
  32. package/lib/tags.d.ts +8 -0
  33. package/lib/tags.js +22 -0
  34. package/lib/theme/hooks/useDocs.js +21 -21
  35. package/lib/translations.d.ts +1 -1
  36. package/lib/translations.js +13 -13
  37. package/lib/types.d.ts +29 -61
  38. package/lib/versions.d.ts +1 -1
  39. package/lib/versions.js +40 -20
  40. package/package.json +15 -14
  41. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  42. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +1 -0
  43. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  44. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  45. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  46. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  47. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  48. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  49. package/src/__tests__/__snapshots__/cli.test.ts.snap +28 -0
  50. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  51. package/src/__tests__/__snapshots__/index.test.ts.snap +426 -25
  52. package/src/__tests__/docFrontMatter.test.ts +160 -45
  53. package/src/__tests__/docs.test.ts +167 -21
  54. package/src/__tests__/index.test.ts +53 -27
  55. package/src/__tests__/options.test.ts +4 -1
  56. package/src/__tests__/props.test.ts +62 -0
  57. package/src/__tests__/versions.test.ts +68 -63
  58. package/src/cli.ts +23 -30
  59. package/src/client/docsClientUtils.ts +1 -12
  60. package/src/docFrontMatter.ts +7 -2
  61. package/src/docs.ts +88 -9
  62. package/src/index.ts +77 -91
  63. package/src/markdown/index.ts +8 -12
  64. package/src/numberPrefix.ts +4 -2
  65. package/src/options.ts +13 -1
  66. package/src/plugin-content-docs.d.ts +107 -32
  67. package/src/props.ts +41 -5
  68. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  69. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  70. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  71. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  72. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  73. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  74. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  75. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  76. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  77. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  78. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  79. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  80. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  81. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  82. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +6 -6
  83. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +2 -2
  84. package/src/sidebars/__tests__/index.test.ts +202 -0
  85. package/src/sidebars/__tests__/processor.test.ts +148 -0
  86. package/src/sidebars/__tests__/utils.test.ts +395 -0
  87. package/src/sidebars/generator.ts +253 -0
  88. package/src/sidebars/index.ts +84 -0
  89. package/src/sidebars/normalization.ts +88 -0
  90. package/src/sidebars/processor.ts +124 -0
  91. package/src/sidebars/types.ts +156 -0
  92. package/src/sidebars/utils.ts +146 -0
  93. package/src/sidebars/validation.ts +124 -0
  94. package/src/tags.ts +21 -0
  95. package/src/translations.ts +26 -36
  96. package/src/types.ts +35 -101
  97. package/src/versions.ts +51 -21
  98. package/lib/sidebarItemsGenerator.js +0 -215
  99. package/lib/sidebars.d.ts +0 -45
  100. package/lib/sidebars.js +0 -354
  101. package/src/__tests__/sidebars.test.ts +0 -746
  102. package/src/sidebarItemsGenerator.ts +0 -315
  103. package/src/sidebars.ts +0 -589
package/lib/docs.js CHANGED
@@ -6,24 +6,26 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
9
+ exports.handleNavigation = exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const path_1 = tslib_1.__importDefault(require("path"));
12
- const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
11
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
12
+ const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
13
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
14
+ const lodash_1 = require("lodash");
13
15
  const utils_1 = require("@docusaurus/utils");
14
16
  const lastUpdate_1 = require("./lastUpdate");
15
- const slug_1 = tslib_1.__importDefault(require("./slug"));
17
+ const slug_1 = (0, tslib_1.__importDefault)(require("./slug"));
16
18
  const constants_1 = require("./constants");
17
19
  const versions_1 = require("./versions");
18
20
  const numberPrefix_1 = require("./numberPrefix");
19
21
  const docFrontMatter_1 = require("./docFrontMatter");
20
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
22
+ const utils_2 = require("./sidebars/utils");
21
23
  async function readLastUpdateData(filePath, options) {
22
24
  const { showLastUpdateAuthor, showLastUpdateTime } = options;
23
25
  if (showLastUpdateAuthor || showLastUpdateTime) {
24
26
  // Use fake data in dev for faster development.
25
27
  const fileLastUpdateData = process.env.NODE_ENV === 'production'
26
- ? await lastUpdate_1.getFileLastUpdate(filePath)
28
+ ? await (0, lastUpdate_1.getFileLastUpdate)(filePath)
27
29
  : {
28
30
  author: 'Author',
29
31
  timestamp: 1539502055,
@@ -39,7 +41,7 @@ async function readLastUpdateData(filePath, options) {
39
41
  return {};
40
42
  }
41
43
  async function readDocFile(versionMetadata, source, options) {
42
- const contentPath = await utils_1.getFolderContainingFile(versions_1.getDocsDirPaths(versionMetadata), source);
44
+ const contentPath = await (0, utils_1.getFolderContainingFile)((0, versions_1.getDocsDirPaths)(versionMetadata), source);
43
45
  const filePath = path_1.default.join(contentPath, source);
44
46
  const [content, lastUpdate] = await Promise.all([
45
47
  fs_extra_1.default.readFile(filePath, 'utf-8'),
@@ -49,7 +51,7 @@ async function readDocFile(versionMetadata, source, options) {
49
51
  }
50
52
  exports.readDocFile = readDocFile;
51
53
  async function readVersionDocs(versionMetadata, options) {
52
- const sources = await utils_1.Globby(options.include, {
54
+ const sources = await (0, utils_1.Globby)(options.include, {
53
55
  cwd: versionMetadata.contentPath,
54
56
  ignore: options.exclude,
55
57
  });
@@ -61,21 +63,19 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
61
63
  const { source, content, lastUpdate, contentPath, filePath } = docFile;
62
64
  const { homePageId } = options;
63
65
  const { siteDir, i18n } = context;
64
- const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = utils_1.parseMarkdownString(content);
65
- const frontMatter = docFrontMatter_1.validateDocFrontMatter(unsafeFrontMatter);
66
+ const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = (0, utils_1.parseMarkdownString)(content);
67
+ const frontMatter = (0, docFrontMatter_1.validateDocFrontMatter)(unsafeFrontMatter);
66
68
  const { custom_edit_url: customEditURL,
67
69
  // Strip number prefixes by default (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc) by default,
68
- // but allow to disable this behavior with frontmatterr
69
- // eslint-disable-next-line camelcase
70
- parse_number_prefixes = true, } = frontMatter;
70
+ // but allow to disable this behavior with frontmatter
71
+ parse_number_prefixes: parseNumberPrefixes = true, } = frontMatter;
71
72
  // ex: api/plugins/myDoc -> myDoc
72
73
  // ex: myDoc -> myDoc
73
74
  const sourceFileNameWithoutExtension = path_1.default.basename(source, path_1.default.extname(source));
74
75
  // ex: api/plugins/myDoc -> api/plugins
75
76
  // ex: myDoc -> .
76
77
  const sourceDirName = path_1.default.dirname(source);
77
- // eslint-disable-next-line camelcase
78
- const { filename: unprefixedFileName, numberPrefix } = parse_number_prefixes
78
+ const { filename: unprefixedFileName, numberPrefix } = parseNumberPrefixes
79
79
  ? options.numberPrefixParser(sourceFileNameWithoutExtension)
80
80
  : { filename: sourceFileNameWithoutExtension, numberPrefix: undefined };
81
81
  const baseID = (_a = frontMatter.id) !== null && _a !== void 0 ? _a : unprefixedFileName;
@@ -97,9 +97,8 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
97
97
  return undefined;
98
98
  }
99
99
  // Eventually remove the number prefixes from intermediate directories
100
- // eslint-disable-next-line camelcase
101
- return parse_number_prefixes
102
- ? numberPrefix_1.stripPathNumberPrefixes(sourceDirName, options.numberPrefixParser)
100
+ return parseNumberPrefixes
101
+ ? (0, numberPrefix_1.stripPathNumberPrefixes)(sourceDirName, options.numberPrefixParser)
103
102
  : sourceDirName;
104
103
  }
105
104
  const unversionedId = [computeDirNameIdPrefix(), baseID]
@@ -115,25 +114,25 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
115
114
  }
116
115
  const docSlug = isDocsHomePage
117
116
  ? '/'
118
- : slug_1.default({
117
+ : (0, slug_1.default)({
119
118
  baseID,
120
119
  dirName: sourceDirName,
121
120
  frontmatterSlug: frontMatter.slug,
122
- stripDirNumberPrefixes: parse_number_prefixes,
121
+ stripDirNumberPrefixes: parseNumberPrefixes,
123
122
  numberPrefixParser: options.numberPrefixParser,
124
123
  });
125
124
  // Note: the title is used by default for page title, sidebar label, pagination buttons...
126
125
  // frontMatter.title should be used in priority over contentTitle (because it can contain markdown/JSX syntax)
127
126
  const title = (_d = (_c = frontMatter.title) !== null && _c !== void 0 ? _c : contentTitle) !== null && _d !== void 0 ? _d : baseID;
128
127
  const description = (_f = (_e = frontMatter.description) !== null && _e !== void 0 ? _e : excerpt) !== null && _f !== void 0 ? _f : '';
129
- const permalink = utils_1.normalizeUrl([versionMetadata.versionPath, docSlug]);
128
+ const permalink = (0, utils_1.normalizeUrl)([versionMetadata.versionPath, docSlug]);
130
129
  function getDocEditUrl() {
131
130
  const relativeFilePath = path_1.default.relative(contentPath, filePath);
132
131
  if (typeof options.editUrl === 'function') {
133
132
  return options.editUrl({
134
133
  version: versionMetadata.versionName,
135
- versionDocsDirPath: utils_1.posixPath(path_1.default.relative(siteDir, versionMetadata.contentPath)),
136
- docPath: utils_1.posixPath(relativeFilePath),
134
+ versionDocsDirPath: (0, utils_1.posixPath)(path_1.default.relative(siteDir, versionMetadata.contentPath)),
135
+ docPath: (0, utils_1.posixPath)(relativeFilePath),
137
136
  permalink,
138
137
  locale: context.i18n.currentLocale,
139
138
  });
@@ -143,7 +142,7 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
143
142
  const baseVersionEditUrl = isLocalized && options.editLocalizedFiles
144
143
  ? versionMetadata.versionEditUrlLocalized
145
144
  : versionMetadata.versionEditUrl;
146
- return utils_1.getEditUrl(relativeFilePath, baseVersionEditUrl);
145
+ return (0, utils_1.getEditUrl)(relativeFilePath, baseVersionEditUrl);
147
146
  }
148
147
  else {
149
148
  return undefined;
@@ -159,11 +158,12 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
159
158
  isDocsHomePage,
160
159
  title,
161
160
  description,
162
- source: utils_1.aliasedSitePath(filePath, siteDir),
161
+ source: (0, utils_1.aliasedSitePath)(filePath, siteDir),
163
162
  sourceDirName,
164
163
  slug: docSlug,
165
164
  permalink,
166
165
  editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
166
+ tags: (0, utils_1.normalizeFrontMatterTags)(versionMetadata.tagsPath, frontMatter.tags),
167
167
  version: versionMetadata.versionName,
168
168
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
169
169
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
@@ -184,3 +184,54 @@ function processDocMetadata(args) {
184
184
  }
185
185
  }
186
186
  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);
192
+ // Add sidebar/next/previous to the docs
193
+ function addNavData(doc) {
194
+ const { sidebarName, previousId, nextId } = getDocNavigation(doc.id);
195
+ const toDocNavLink = (docId, type) => {
196
+ var _a;
197
+ if (!docId) {
198
+ return undefined;
199
+ }
200
+ if (!docsBaseById[docId]) {
201
+ // This could only happen if user provided the ID through front matter
202
+ throw new Error(`Error when loading ${doc.id} in ${doc.sourceDirName}: the pagination_${type} front matter points to a non-existent ID ${docId}.`);
203
+ }
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 };
206
+ };
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 };
211
+ }
212
+ const docs = docsBase.map(addNavData);
213
+ // 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
+ */
222
+ function getMainDoc() {
223
+ const versionHomeDoc = docs.find((doc) => doc.slug === '/');
224
+ const firstDocIdOfFirstSidebar = getFirstDocIdOfFirstSidebar();
225
+ if (versionHomeDoc) {
226
+ return versionHomeDoc;
227
+ }
228
+ else if (firstDocIdOfFirstSidebar) {
229
+ return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar);
230
+ }
231
+ else {
232
+ return docs[0];
233
+ }
234
+ }
235
+ return { mainDocId: getMainDoc().unversionedId, docs };
236
+ }
237
+ exports.handleNavigation = handleNavigation;
package/lib/index.js CHANGED
@@ -8,10 +8,11 @@
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"));
11
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
12
12
  const constants_1 = require("@docusaurus/core/lib/constants");
13
13
  const utils_1 = require("@docusaurus/utils");
14
14
  const sidebars_1 = require("./sidebars");
15
+ const generator_1 = require("./sidebars/generator");
15
16
  const docs_1 = require("./docs");
16
17
  const versions_1 = require("./versions");
17
18
  const cli_1 = require("./cli");
@@ -20,16 +21,16 @@ const lodash_1 = require("lodash");
20
21
  const globalData_1 = require("./globalData");
21
22
  const props_1 = require("./props");
22
23
  const translations_1 = require("./translations");
23
- const sidebarItemsGenerator_1 = require("./sidebarItemsGenerator");
24
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
24
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
25
+ const tags_1 = require("./tags");
25
26
  function pluginContentDocs(context, options) {
26
27
  var _a;
27
28
  const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
28
- const versionsMetadata = versions_1.readVersionsMetadata({ context, options });
29
+ const versionsMetadata = (0, versions_1.readVersionsMetadata)({ context, options });
29
30
  const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_PLUGIN_ID;
30
31
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-docs');
31
32
  const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
32
- const aliasedSource = (source) => `~docs/${utils_1.posixPath(path_1.default.relative(pluginDataDirRoot, source))}`;
33
+ const aliasedSource = (source) => `~docs/${(0, utils_1.posixPath)(path_1.default.relative(pluginDataDirRoot, source))}`;
33
34
  return {
34
35
  name: 'docusaurus-plugin-content-docs',
35
36
  getThemePath() {
@@ -53,7 +54,7 @@ function pluginContentDocs(context, options) {
53
54
  .arguments('<version>')
54
55
  .description(commandDescription)
55
56
  .action((version) => {
56
- cli_1.cliDocsVersionCommand(version, siteDir, pluginId, {
57
+ (0, cli_1.cliDocsVersionCommand)(version, siteDir, pluginId, {
57
58
  path: options.path,
58
59
  sidebarPath: options.sidebarPath,
59
60
  sidebarCollapsed: options.sidebarCollapsed,
@@ -62,29 +63,29 @@ function pluginContentDocs(context, options) {
62
63
  });
63
64
  },
64
65
  async getTranslationFiles({ content }) {
65
- return translations_1.getLoadedContentTranslationFiles(content);
66
+ return (0, translations_1.getLoadedContentTranslationFiles)(content);
66
67
  },
67
68
  getPathsToWatch() {
68
69
  function getVersionPathsToWatch(version) {
69
70
  const result = [
70
- ...lodash_1.flatten(options.include.map((pattern) => versions_1.getDocsDirPaths(version).map((docsDirPath) => `${docsDirPath}/${pattern}`))),
71
- `${version.contentPath}/**/${sidebarItemsGenerator_1.CategoryMetadataFilenamePattern}`,
71
+ ...options.include.flatMap((pattern) => (0, versions_1.getDocsDirPaths)(version).map((docsDirPath) => `${docsDirPath}/${pattern}`)),
72
+ `${version.contentPath}/**/${generator_1.CategoryMetadataFilenamePattern}`,
72
73
  ];
73
74
  if (typeof version.sidebarFilePath === 'string') {
74
75
  result.unshift(version.sidebarFilePath);
75
76
  }
76
77
  return result;
77
78
  }
78
- return lodash_1.flatten(versionsMetadata.map(getVersionPathsToWatch));
79
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
79
80
  },
80
81
  async loadContent() {
81
82
  async function loadVersionDocsBase(versionMetadata) {
82
- const docFiles = await docs_1.readVersionDocs(versionMetadata, options);
83
+ const docFiles = await (0, docs_1.readVersionDocs)(versionMetadata, options);
83
84
  if (docFiles.length === 0) {
84
85
  throw new Error(`Docs version "${versionMetadata.versionName}" has no docs! At least one doc should exist at "${path_1.default.relative(siteDir, versionMetadata.contentPath)}".`);
85
86
  }
86
87
  async function processVersionDoc(docFile) {
87
- return docs_1.processDocMetadata({
88
+ return (0, docs_1.processDocMetadata)({
88
89
  docFile,
89
90
  versionMetadata,
90
91
  context,
@@ -94,16 +95,10 @@ function pluginContentDocs(context, options) {
94
95
  return Promise.all(docFiles.map(processVersionDoc));
95
96
  }
96
97
  async function doLoadVersion(versionMetadata) {
97
- const unprocessedSidebars = sidebars_1.loadSidebars(versionMetadata.sidebarFilePath, {
98
- sidebarCollapsed: options.sidebarCollapsed,
99
- sidebarCollapsible: options.sidebarCollapsible,
100
- });
101
98
  const docsBase = await loadVersionDocsBase(versionMetadata);
102
- const docsBaseById = lodash_1.keyBy(docsBase, (doc) => doc.id);
103
- const sidebars = await sidebars_1.processSidebars({
99
+ const sidebars = await (0, sidebars_1.loadSidebars)(versionMetadata.sidebarFilePath, {
104
100
  sidebarItemsGenerator: options.sidebarItemsGenerator,
105
101
  numberPrefixParser: options.numberPrefixParser,
106
- unprocessedSidebars,
107
102
  docs: docsBase,
108
103
  version: versionMetadata,
109
104
  options: {
@@ -111,53 +106,10 @@ function pluginContentDocs(context, options) {
111
106
  sidebarCollapsible: options.sidebarCollapsible,
112
107
  },
113
108
  });
114
- const sidebarsUtils = sidebars_1.createSidebarsUtils(sidebars);
115
- const validDocIds = Object.keys(docsBaseById);
116
- sidebarsUtils.checkSidebarsDocIds(validDocIds, versionMetadata.sidebarFilePath);
117
- // Add sidebar/next/previous to the docs
118
- function addNavData(doc) {
119
- const { sidebarName, previousId, nextId, } = sidebarsUtils.getDocNavigation(doc.id);
120
- const toDocNavLink = (navDocId) => {
121
- var _a, _b;
122
- const { title, permalink, frontMatter } = docsBaseById[navDocId];
123
- return {
124
- title: (_b = (_a = frontMatter.pagination_label) !== null && _a !== void 0 ? _a : frontMatter.sidebar_label) !== null && _b !== void 0 ? _b : title,
125
- permalink,
126
- };
127
- };
128
- return {
129
- ...doc,
130
- sidebar: sidebarName,
131
- previous: previousId ? toDocNavLink(previousId) : undefined,
132
- next: nextId ? toDocNavLink(nextId) : undefined,
133
- };
134
- }
135
- const docs = docsBase.map(addNavData);
136
- // sort to ensure consistent output for tests
137
- docs.sort((a, b) => a.id.localeCompare(b.id));
138
- // The "main doc" is the "version entry point"
139
- // We browse this doc by clicking on a version:
140
- // - the "home" doc (at '/docs/')
141
- // - the first doc of the first sidebar
142
- // - a random doc (if no docs are in any sidebar... edge case)
143
- function getMainDoc() {
144
- const versionHomeDoc = docs.find((doc) => doc.unversionedId === options.homePageId || doc.slug === '/');
145
- const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
146
- if (versionHomeDoc) {
147
- return versionHomeDoc;
148
- }
149
- else if (firstDocIdOfFirstSidebar) {
150
- return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar);
151
- }
152
- else {
153
- return docs[0];
154
- }
155
- }
156
109
  return {
157
110
  ...versionMetadata,
158
- mainDocId: getMainDoc().unversionedId,
111
+ ...(0, docs_1.handleNavigation)(docsBase, sidebars, versionMetadata.sidebarFilePath),
159
112
  sidebars,
160
- docs: docs.map(addNavData),
161
113
  };
162
114
  }
163
115
  async function loadVersion(versionMetadata) {
@@ -174,7 +126,7 @@ function pluginContentDocs(context, options) {
174
126
  };
175
127
  },
176
128
  translateContent({ content, translationFiles }) {
177
- return translations_1.translateLoadedContent(content, translationFiles);
129
+ return (0, translations_1.translateLoadedContent)(content, translationFiles);
178
130
  },
179
131
  async contentLoaded({ content, actions }) {
180
132
  const { loadedVersions } = content;
@@ -185,7 +137,7 @@ function pluginContentDocs(context, options) {
185
137
  await createData(
186
138
  // Note that this created data path must be in sync with
187
139
  // metadataPath provided to mdx-loader.
188
- `${utils_1.docuHash(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
140
+ `${(0, utils_1.docuHash)(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
189
141
  const docRoute = {
190
142
  path: metadataItem.permalink,
191
143
  component: docItemComponent,
@@ -203,9 +155,50 @@ function pluginContentDocs(context, options) {
203
155
  }));
204
156
  return routes.sort((a, b) => a.path.localeCompare(b.path));
205
157
  };
158
+ async function createVersionTagsRoutes(loadedVersion) {
159
+ const versionTags = (0, tags_1.getVersionTags)(loadedVersion.docs);
160
+ async function createTagsListPage() {
161
+ const tagsProp = Object.values(versionTags).map((tagValue) => ({
162
+ name: tagValue.name,
163
+ permalink: tagValue.permalink,
164
+ count: tagValue.docIds.length,
165
+ }));
166
+ // Only create /tags page if there are tags.
167
+ 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));
169
+ addRoute({
170
+ path: loadedVersion.tagsPath,
171
+ exact: true,
172
+ component: options.docTagsListComponent,
173
+ modules: {
174
+ tags: aliasedSource(tagsPropPath),
175
+ },
176
+ });
177
+ }
178
+ }
179
+ async function createTagDocListPage(tag) {
180
+ const tagProps = (0, props_1.toTagDocListProp)({
181
+ allTagsPath: loadedVersion.tagsPath,
182
+ tag,
183
+ docs: loadedVersion.docs,
184
+ });
185
+ const tagPropPath = await createData(`${(0, utils_1.docuHash)(`tag-${tag.permalink}`)}.json`, JSON.stringify(tagProps, null, 2));
186
+ addRoute({
187
+ path: tag.permalink,
188
+ component: options.docTagDocListComponent,
189
+ exact: true,
190
+ modules: {
191
+ tag: aliasedSource(tagPropPath),
192
+ },
193
+ });
194
+ }
195
+ await createTagsListPage();
196
+ await Promise.all(Object.values(versionTags).map(createTagDocListPage));
197
+ }
206
198
  async function doCreateVersionRoutes(loadedVersion) {
207
- const versionMetadata = props_1.toVersionMetadataProp(pluginId, loadedVersion);
208
- const versionMetadataPropPath = await createData(`${utils_1.docuHash(`version-${loadedVersion.versionName}-metadata-prop`)}.json`, JSON.stringify(versionMetadata, null, 2));
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));
209
202
  addRoute({
210
203
  path: loadedVersion.versionPath,
211
204
  // allow matching /docs/* as well
@@ -231,7 +224,7 @@ function pluginContentDocs(context, options) {
231
224
  }
232
225
  await Promise.all(loadedVersions.map(createVersionRoutes));
233
226
  setGlobalData({
234
- path: utils_1.normalizeUrl([baseUrl, options.routeBasePath]),
227
+ path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
235
228
  versions: loadedVersions.map(globalData_1.toGlobalDataVersion),
236
229
  });
237
230
  },
@@ -239,8 +232,8 @@ function pluginContentDocs(context, options) {
239
232
  const { getJSLoader } = utils;
240
233
  const { rehypePlugins, remarkPlugins, beforeDefaultRehypePlugins, beforeDefaultRemarkPlugins, } = options;
241
234
  function getSourceToPermalink() {
242
- const allDocs = lodash_1.flatten(content.loadedVersions.map((v) => v.docs));
243
- return lodash_1.mapValues(lodash_1.keyBy(allDocs, (d) => d.source), (d) => d.permalink);
235
+ const allDocs = content.loadedVersions.flatMap((v) => v.docs);
236
+ return (0, lodash_1.mapValues)((0, lodash_1.keyBy)(allDocs, (d) => d.source), (d) => d.permalink);
244
237
  }
245
238
  const docsMarkdownOptions = {
246
239
  siteDir,
@@ -250,17 +243,17 @@ function pluginContentDocs(context, options) {
250
243
  if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
251
244
  return;
252
245
  }
253
- utils_1.reportMessage(`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.contentPaths.versionName}`, siteConfig.onBrokenMarkdownLinks);
246
+ (0, utils_1.reportMessage)(`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.contentPaths.versionName}`, siteConfig.onBrokenMarkdownLinks);
254
247
  },
255
248
  };
256
249
  function createMDXLoaderRule() {
257
- const contentDirs = lodash_1.flatten(versionsMetadata.map(versions_1.getDocsDirPaths));
250
+ const contentDirs = versionsMetadata.flatMap(versions_1.getDocsDirPaths);
258
251
  return {
259
252
  test: /(\.mdx?)$/,
260
253
  include: contentDirs
261
254
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
262
255
  .map(utils_1.addTrailingPathSeparator),
263
- use: lodash_1.compact([
256
+ use: [
264
257
  getJSLoader({ isServer }),
265
258
  {
266
259
  loader: require.resolve('@docusaurus/mdx-loader'),
@@ -270,12 +263,12 @@ function pluginContentDocs(context, options) {
270
263
  beforeDefaultRehypePlugins,
271
264
  beforeDefaultRemarkPlugins,
272
265
  staticDir: path_1.default.join(siteDir, constants_1.STATIC_DIR_NAME),
273
- isMDXPartial: utils_1.createAbsoluteFilePathMatcher(options.exclude, contentDirs),
266
+ isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
274
267
  metadataPath: (mdxPath) => {
275
268
  // Note that metadataPath must be the same/in-sync as
276
269
  // the path from createData for each MDX.
277
- const aliasedPath = utils_1.aliasedSitePath(mdxPath, siteDir);
278
- return path_1.default.join(dataDir, `${utils_1.docuHash(aliasedPath)}.json`);
270
+ const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
271
+ return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
279
272
  },
280
273
  },
281
274
  },
@@ -283,7 +276,7 @@ function pluginContentDocs(context, options) {
283
276
  loader: path_1.default.resolve(__dirname, './markdown/index.js'),
284
277
  options: docsMarkdownOptions,
285
278
  },
286
- ]),
279
+ ].filter(Boolean),
287
280
  };
288
281
  }
289
282
  return {
package/lib/lastUpdate.js CHANGED
@@ -8,9 +8,9 @@
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 path_1 = tslib_1.__importDefault(require("path"));
11
+ const shelljs_1 = (0, tslib_1.__importDefault)(require("shelljs"));
12
+ const execa_1 = (0, tslib_1.__importDefault)(require("execa"));
13
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
14
14
  const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+), (.+)$/;
15
15
  let showedGitRequirementError = false;
16
16
  async function getFileLastUpdate(filePath) {
@@ -38,7 +38,7 @@ async function getFileLastUpdate(filePath) {
38
38
  }
39
39
  const fileBasename = path_1.default.basename(filePath);
40
40
  const fileDirname = path_1.default.dirname(filePath);
41
- const { stdout } = await execa_1.default('git', ['log', '-1', '--format=%ct, %an', fileBasename], {
41
+ const { stdout } = await (0, execa_1.default)('git', ['log', '-1', '--format=%ct, %an', fileBasename], {
42
42
  cwd: fileDirname,
43
43
  });
44
44
  return getTimestampAndAuthor(stdout);
@@ -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,
package/lib/options.js CHANGED
@@ -4,20 +4,23 @@ exports.validateOptions = exports.OptionsSchema = exports.DEFAULT_OPTIONS = void
4
4
  const tslib_1 = require("tslib");
5
5
  const utils_validation_1 = require("@docusaurus/utils-validation");
6
6
  const utils_1 = require("@docusaurus/utils");
7
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
- const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
9
- const sidebarItemsGenerator_1 = require("./sidebarItemsGenerator");
7
+ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
+ const remark_admonitions_1 = (0, tslib_1.__importDefault)(require("remark-admonitions"));
9
+ const generator_1 = require("./sidebars/generator");
10
10
  const numberPrefix_1 = require("./numberPrefix");
11
11
  exports.DEFAULT_OPTIONS = {
12
12
  path: 'docs',
13
13
  routeBasePath: 'docs',
14
+ tagsBasePath: 'tags',
14
15
  homePageId: undefined,
15
16
  include: ['**/*.{md,mdx}'],
16
17
  exclude: utils_1.GlobExcludeDefault,
17
- sidebarItemsGenerator: sidebarItemsGenerator_1.DefaultSidebarItemsGenerator,
18
+ sidebarItemsGenerator: generator_1.DefaultSidebarItemsGenerator,
18
19
  numberPrefixParser: numberPrefix_1.DefaultNumberPrefixParser,
19
20
  docLayoutComponent: '@theme/DocPage',
20
21
  docItemComponent: '@theme/DocItem',
22
+ docTagDocListComponent: '@theme/DocTagDocListPage',
23
+ docTagsListComponent: '@theme/DocTagsListPage',
21
24
  remarkPlugins: [],
22
25
  rehypePlugins: [],
23
26
  beforeDefaultRemarkPlugins: [],
@@ -38,6 +41,8 @@ const VersionOptionsSchema = utils_validation_1.Joi.object({
38
41
  path: utils_validation_1.Joi.string().allow('').optional(),
39
42
  label: utils_validation_1.Joi.string().optional(),
40
43
  banner: utils_validation_1.Joi.string().equal('none', 'unreleased', 'unmaintained').optional(),
44
+ badge: utils_validation_1.Joi.boolean().optional(),
45
+ className: utils_validation_1.Joi.string().optional(),
41
46
  });
42
47
  const VersionsOptionsSchema = utils_validation_1.Joi.object()
43
48
  .pattern(utils_validation_1.Joi.string().required(), VersionOptionsSchema)
@@ -51,6 +56,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
51
56
  // '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
52
57
  // .allow('') ""
53
58
  .default(exports.DEFAULT_OPTIONS.routeBasePath),
59
+ tagsBasePath: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.tagsBasePath),
54
60
  homePageId: utils_validation_1.Joi.string().optional(),
55
61
  include: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string()).default(exports.DEFAULT_OPTIONS.include),
56
62
  exclude: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string()).default(exports.DEFAULT_OPTIONS.exclude),
@@ -67,6 +73,8 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
67
73
  .default(() => exports.DEFAULT_OPTIONS.numberPrefixParser),
68
74
  docLayoutComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docLayoutComponent),
69
75
  docItemComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docItemComponent),
76
+ docTagsListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagsListComponent),
77
+ docTagDocListComponent: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.docTagDocListComponent),
70
78
  remarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.remarkPlugins),
71
79
  rehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.rehypePlugins),
72
80
  beforeDefaultRemarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.beforeDefaultRemarkPlugins),
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 { LoadedVersion, VersionTag, DocMetadata } from './types';
8
+ import type { PropSidebars, PropVersionMetadata, PropTagDocList } from '@docusaurus/plugin-content-docs-types';
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;