@docusaurus/plugin-content-docs 2.0.0-beta.8bda3b2db → 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 (117) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/cli.d.ts +2 -2
  3. package/lib/cli.js +20 -24
  4. package/lib/client/docsClientUtils.d.ts +1 -4
  5. package/lib/client/docsClientUtils.js +12 -16
  6. package/lib/docFrontMatter.js +7 -3
  7. package/lib/docs.d.ts +4 -2
  8. package/lib/docs.js +77 -23
  9. package/lib/index.js +88 -94
  10. package/lib/lastUpdate.js +8 -8
  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.d.ts +1 -1
  15. package/lib/options.js +39 -11
  16. package/lib/props.d.ts +7 -2
  17. package/lib/props.js +27 -4
  18. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +3 -1
  19. package/lib/sidebars/generator.js +174 -0
  20. package/lib/sidebars/index.d.ts +14 -0
  21. package/lib/sidebars/index.js +64 -0
  22. package/lib/sidebars/normalization.d.ts +9 -0
  23. package/lib/sidebars/normalization.js +58 -0
  24. package/lib/sidebars/processor.d.ts +16 -0
  25. package/lib/sidebars/processor.js +70 -0
  26. package/lib/sidebars/types.d.ts +87 -0
  27. package/lib/sidebars/types.js +13 -0
  28. package/lib/sidebars/utils.d.ts +22 -0
  29. package/lib/sidebars/utils.js +101 -0
  30. package/lib/sidebars/validation.d.ts +8 -0
  31. package/lib/sidebars/validation.js +102 -0
  32. package/lib/slug.js +4 -4
  33. package/lib/tags.d.ts +8 -0
  34. package/lib/tags.js +22 -0
  35. package/lib/theme/hooks/useDocs.js +24 -21
  36. package/lib/translations.d.ts +1 -1
  37. package/lib/translations.js +13 -13
  38. package/lib/types.d.ts +35 -58
  39. package/lib/versions.d.ts +1 -1
  40. package/lib/versions.js +75 -22
  41. package/package.json +15 -14
  42. package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
  43. package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
  44. package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
  45. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  46. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +1 -0
  47. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  48. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  49. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  50. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  51. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  52. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  53. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
  54. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
  55. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
  56. package/src/__tests__/__snapshots__/cli.test.ts.snap +33 -0
  57. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  58. package/src/__tests__/__snapshots__/index.test.ts.snap +478 -60
  59. package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -3
  60. package/src/__tests__/cli.test.ts +14 -10
  61. package/src/__tests__/docFrontMatter.test.ts +163 -48
  62. package/src/__tests__/docs.test.ts +167 -21
  63. package/src/__tests__/index.test.ts +74 -30
  64. package/src/__tests__/lastUpdate.test.ts +3 -2
  65. package/src/__tests__/options.test.ts +46 -3
  66. package/src/__tests__/props.test.ts +62 -0
  67. package/src/__tests__/translations.test.ts +0 -1
  68. package/src/__tests__/versions.test.ts +88 -60
  69. package/src/cli.ts +27 -30
  70. package/src/client/__tests__/docsClientUtils.test.ts +4 -5
  71. package/src/client/docsClientUtils.ts +6 -27
  72. package/src/docFrontMatter.ts +8 -3
  73. package/src/docs.ts +92 -9
  74. package/src/index.ts +114 -121
  75. package/src/lastUpdate.ts +10 -6
  76. package/src/markdown/index.ts +8 -12
  77. package/src/numberPrefix.ts +4 -2
  78. package/src/options.ts +47 -17
  79. package/src/plugin-content-docs.d.ts +121 -34
  80. package/src/props.ts +42 -6
  81. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  82. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  83. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  84. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  85. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  86. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  87. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  88. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  89. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  90. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  91. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  92. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  93. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  94. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  95. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +21 -6
  96. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +29 -7
  97. package/src/sidebars/__tests__/index.test.ts +202 -0
  98. package/src/sidebars/__tests__/processor.test.ts +148 -0
  99. package/src/sidebars/__tests__/utils.test.ts +395 -0
  100. package/src/sidebars/generator.ts +253 -0
  101. package/src/sidebars/index.ts +84 -0
  102. package/src/sidebars/normalization.ts +88 -0
  103. package/src/sidebars/processor.ts +124 -0
  104. package/src/sidebars/types.ts +156 -0
  105. package/src/sidebars/utils.ts +146 -0
  106. package/src/sidebars/validation.ts +124 -0
  107. package/src/tags.ts +21 -0
  108. package/src/theme/hooks/useDocs.ts +5 -1
  109. package/src/translations.ts +26 -36
  110. package/src/types.ts +48 -99
  111. package/src/versions.ts +109 -17
  112. package/lib/sidebarItemsGenerator.js +0 -211
  113. package/lib/sidebars.d.ts +0 -43
  114. package/lib/sidebars.js +0 -319
  115. package/src/__tests__/sidebars.test.ts +0 -639
  116. package/src/sidebarItemsGenerator.ts +0 -307
  117. package/src/sidebars.ts +0 -506
package/lib/docs.d.ts CHANGED
@@ -5,14 +5,16 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { LoadContext } from '@docusaurus/types';
8
- import { DocFile, DocMetadataBase, MetadataOptions, PluginOptions, VersionMetadata } from './types';
8
+ import { DocFile, DocMetadataBase, MetadataOptions, PluginOptions, VersionMetadata, LoadedVersion } from './types';
9
+ import type { Sidebars } from './sidebars/types';
9
10
  declare type LastUpdateOptions = Pick<PluginOptions, 'showLastUpdateAuthor' | 'showLastUpdateTime'>;
10
11
  export declare function readDocFile(versionMetadata: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'>, source: string, options: LastUpdateOptions): Promise<DocFile>;
11
- export declare function readVersionDocs(versionMetadata: VersionMetadata, options: Pick<PluginOptions, 'include' | 'showLastUpdateAuthor' | 'showLastUpdateTime'>): Promise<DocFile[]>;
12
+ export declare function readVersionDocs(versionMetadata: VersionMetadata, options: Pick<PluginOptions, 'include' | 'exclude' | 'showLastUpdateAuthor' | 'showLastUpdateTime'>): Promise<DocFile[]>;
12
13
  export declare function processDocMetadata(args: {
13
14
  docFile: DocFile;
14
15
  versionMetadata: VersionMetadata;
15
16
  context: LoadContext;
16
17
  options: MetadataOptions;
17
18
  }): DocMetadataBase;
19
+ export declare function handleNavigation(docsBase: DocMetadataBase[], sidebars: Sidebars, sidebarFilePath: string): Pick<LoadedVersion, 'mainDocId' | 'docs'>;
18
20
  export {};
package/lib/docs.js CHANGED
@@ -6,25 +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
- const globby_1 = tslib_1.__importDefault(require("globby"));
18
19
  const versions_1 = require("./versions");
19
20
  const numberPrefix_1 = require("./numberPrefix");
20
21
  const docFrontMatter_1 = require("./docFrontMatter");
21
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
22
+ const utils_2 = require("./sidebars/utils");
22
23
  async function readLastUpdateData(filePath, options) {
23
24
  const { showLastUpdateAuthor, showLastUpdateTime } = options;
24
25
  if (showLastUpdateAuthor || showLastUpdateTime) {
25
26
  // Use fake data in dev for faster development.
26
27
  const fileLastUpdateData = process.env.NODE_ENV === 'production'
27
- ? await lastUpdate_1.getFileLastUpdate(filePath)
28
+ ? await (0, lastUpdate_1.getFileLastUpdate)(filePath)
28
29
  : {
29
30
  author: 'Author',
30
31
  timestamp: 1539502055,
@@ -40,7 +41,7 @@ async function readLastUpdateData(filePath, options) {
40
41
  return {};
41
42
  }
42
43
  async function readDocFile(versionMetadata, source, options) {
43
- 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);
44
45
  const filePath = path_1.default.join(contentPath, source);
45
46
  const [content, lastUpdate] = await Promise.all([
46
47
  fs_extra_1.default.readFile(filePath, 'utf-8'),
@@ -50,8 +51,9 @@ async function readDocFile(versionMetadata, source, options) {
50
51
  }
51
52
  exports.readDocFile = readDocFile;
52
53
  async function readVersionDocs(versionMetadata, options) {
53
- const sources = await globby_1.default(options.include, {
54
+ const sources = await (0, utils_1.Globby)(options.include, {
54
55
  cwd: versionMetadata.contentPath,
56
+ ignore: options.exclude,
55
57
  });
56
58
  return Promise.all(sources.map((source) => readDocFile(versionMetadata, source, options)));
57
59
  }
@@ -61,19 +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
- parse_number_prefixes = true, } = frontMatter;
70
+ // but allow to disable this behavior with frontmatter
71
+ parse_number_prefixes: parseNumberPrefixes = true, } = frontMatter;
70
72
  // ex: api/plugins/myDoc -> myDoc
71
73
  // ex: myDoc -> myDoc
72
74
  const sourceFileNameWithoutExtension = path_1.default.basename(source, path_1.default.extname(source));
73
75
  // ex: api/plugins/myDoc -> api/plugins
74
76
  // ex: myDoc -> .
75
77
  const sourceDirName = path_1.default.dirname(source);
76
- const { filename: unprefixedFileName, numberPrefix } = parse_number_prefixes
78
+ const { filename: unprefixedFileName, numberPrefix } = parseNumberPrefixes
77
79
  ? options.numberPrefixParser(sourceFileNameWithoutExtension)
78
80
  : { filename: sourceFileNameWithoutExtension, numberPrefix: undefined };
79
81
  const baseID = (_a = frontMatter.id) !== null && _a !== void 0 ? _a : unprefixedFileName;
@@ -95,8 +97,8 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
95
97
  return undefined;
96
98
  }
97
99
  // Eventually remove the number prefixes from intermediate directories
98
- return parse_number_prefixes
99
- ? numberPrefix_1.stripPathNumberPrefixes(sourceDirName, options.numberPrefixParser)
100
+ return parseNumberPrefixes
101
+ ? (0, numberPrefix_1.stripPathNumberPrefixes)(sourceDirName, options.numberPrefixParser)
100
102
  : sourceDirName;
101
103
  }
102
104
  const unversionedId = [computeDirNameIdPrefix(), baseID]
@@ -112,25 +114,25 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
112
114
  }
113
115
  const docSlug = isDocsHomePage
114
116
  ? '/'
115
- : slug_1.default({
117
+ : (0, slug_1.default)({
116
118
  baseID,
117
119
  dirName: sourceDirName,
118
120
  frontmatterSlug: frontMatter.slug,
119
- stripDirNumberPrefixes: parse_number_prefixes,
121
+ stripDirNumberPrefixes: parseNumberPrefixes,
120
122
  numberPrefixParser: options.numberPrefixParser,
121
123
  });
122
124
  // Note: the title is used by default for page title, sidebar label, pagination buttons...
123
125
  // frontMatter.title should be used in priority over contentTitle (because it can contain markdown/JSX syntax)
124
126
  const title = (_d = (_c = frontMatter.title) !== null && _c !== void 0 ? _c : contentTitle) !== null && _d !== void 0 ? _d : baseID;
125
127
  const description = (_f = (_e = frontMatter.description) !== null && _e !== void 0 ? _e : excerpt) !== null && _f !== void 0 ? _f : '';
126
- const permalink = utils_1.normalizeUrl([versionMetadata.versionPath, docSlug]);
128
+ const permalink = (0, utils_1.normalizeUrl)([versionMetadata.versionPath, docSlug]);
127
129
  function getDocEditUrl() {
128
130
  const relativeFilePath = path_1.default.relative(contentPath, filePath);
129
131
  if (typeof options.editUrl === 'function') {
130
132
  return options.editUrl({
131
133
  version: versionMetadata.versionName,
132
- versionDocsDirPath: utils_1.posixPath(path_1.default.relative(siteDir, versionMetadata.contentPath)),
133
- 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),
134
136
  permalink,
135
137
  locale: context.i18n.currentLocale,
136
138
  });
@@ -140,7 +142,7 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
140
142
  const baseVersionEditUrl = isLocalized && options.editLocalizedFiles
141
143
  ? versionMetadata.versionEditUrlLocalized
142
144
  : versionMetadata.versionEditUrl;
143
- return utils_1.getEditUrl(relativeFilePath, baseVersionEditUrl);
145
+ return (0, utils_1.getEditUrl)(relativeFilePath, baseVersionEditUrl);
144
146
  }
145
147
  else {
146
148
  return undefined;
@@ -156,11 +158,12 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
156
158
  isDocsHomePage,
157
159
  title,
158
160
  description,
159
- source: utils_1.aliasedSitePath(filePath, siteDir),
161
+ source: (0, utils_1.aliasedSitePath)(filePath, siteDir),
160
162
  sourceDirName,
161
163
  slug: docSlug,
162
164
  permalink,
163
165
  editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
166
+ tags: (0, utils_1.normalizeFrontMatterTags)(versionMetadata.tagsPath, frontMatter.tags),
164
167
  version: versionMetadata.versionName,
165
168
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
166
169
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
@@ -181,3 +184,54 @@ function processDocMetadata(args) {
181
184
  }
182
185
  }
183
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,17 +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 sourceToPermalink = {};
29
+ const versionsMetadata = (0, versions_1.readVersionsMetadata)({ context, options });
30
30
  const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_PLUGIN_ID;
31
31
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-docs');
32
32
  const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
33
- 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))}`;
34
34
  return {
35
35
  name: 'docusaurus-plugin-content-docs',
36
36
  getThemePath() {
@@ -54,43 +54,38 @@ function pluginContentDocs(context, options) {
54
54
  .arguments('<version>')
55
55
  .description(commandDescription)
56
56
  .action((version) => {
57
- cli_1.cliDocsVersionCommand(version, siteDir, pluginId, {
57
+ (0, cli_1.cliDocsVersionCommand)(version, siteDir, pluginId, {
58
58
  path: options.path,
59
59
  sidebarPath: options.sidebarPath,
60
+ sidebarCollapsed: options.sidebarCollapsed,
61
+ sidebarCollapsible: options.sidebarCollapsible,
60
62
  });
61
63
  });
62
64
  },
63
65
  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;
66
+ return (0, translations_1.getLoadedContentTranslationFiles)(content);
72
67
  },
73
68
  getPathsToWatch() {
74
69
  function getVersionPathsToWatch(version) {
75
70
  const result = [
76
- ...lodash_1.flatten(options.include.map((pattern) => versions_1.getDocsDirPaths(version).map((docsDirPath) => `${docsDirPath}/${pattern}`))),
77
- `${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}`,
78
73
  ];
79
74
  if (typeof version.sidebarFilePath === 'string') {
80
75
  result.unshift(version.sidebarFilePath);
81
76
  }
82
77
  return result;
83
78
  }
84
- return lodash_1.flatten(versionsMetadata.map(getVersionPathsToWatch));
79
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
85
80
  },
86
81
  async loadContent() {
87
82
  async function loadVersionDocsBase(versionMetadata) {
88
- const docFiles = await docs_1.readVersionDocs(versionMetadata, options);
83
+ const docFiles = await (0, docs_1.readVersionDocs)(versionMetadata, options);
89
84
  if (docFiles.length === 0) {
90
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)}".`);
91
86
  }
92
87
  async function processVersionDoc(docFile) {
93
- return docs_1.processDocMetadata({
88
+ return (0, docs_1.processDocMetadata)({
94
89
  docFile,
95
90
  versionMetadata,
96
91
  context,
@@ -100,76 +95,21 @@ function pluginContentDocs(context, options) {
100
95
  return Promise.all(docFiles.map(processVersionDoc));
101
96
  }
102
97
  async function doLoadVersion(versionMetadata) {
103
- const unprocessedSidebars = sidebars_1.loadSidebars(versionMetadata.sidebarFilePath);
104
98
  const docsBase = await loadVersionDocsBase(versionMetadata);
105
- const docsBaseById = lodash_1.keyBy(docsBase, (doc) => doc.id);
106
- const sidebars = await sidebars_1.processSidebars({
99
+ const sidebars = await (0, sidebars_1.loadSidebars)(versionMetadata.sidebarFilePath, {
107
100
  sidebarItemsGenerator: options.sidebarItemsGenerator,
108
101
  numberPrefixParser: options.numberPrefixParser,
109
- unprocessedSidebars,
110
102
  docs: docsBase,
111
103
  version: versionMetadata,
104
+ options: {
105
+ sidebarCollapsed: options.sidebarCollapsed,
106
+ sidebarCollapsible: options.sidebarCollapsible,
107
+ },
112
108
  });
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
- }
167
109
  return {
168
110
  ...versionMetadata,
169
- mainDocId: getMainDoc().unversionedId,
111
+ ...(0, docs_1.handleNavigation)(docsBase, sidebars, versionMetadata.sidebarFilePath),
170
112
  sidebars,
171
- permalinkToSidebar,
172
- docs: docs.map(addNavData),
173
113
  };
174
114
  }
175
115
  async function loadVersion(versionMetadata) {
@@ -186,7 +126,7 @@ function pluginContentDocs(context, options) {
186
126
  };
187
127
  },
188
128
  translateContent({ content, translationFiles }) {
189
- return translations_1.translateLoadedContent(content, translationFiles);
129
+ return (0, translations_1.translateLoadedContent)(content, translationFiles);
190
130
  },
191
131
  async contentLoaded({ content, actions }) {
192
132
  const { loadedVersions } = content;
@@ -197,20 +137,68 @@ function pluginContentDocs(context, options) {
197
137
  await createData(
198
138
  // Note that this created data path must be in sync with
199
139
  // metadataPath provided to mdx-loader.
200
- `${utils_1.docuHash(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
201
- return {
140
+ `${(0, utils_1.docuHash)(metadataItem.source)}.json`, JSON.stringify(metadataItem, null, 2));
141
+ const docRoute = {
202
142
  path: metadataItem.permalink,
203
143
  component: docItemComponent,
204
144
  exact: true,
205
145
  modules: {
206
146
  content: metadataItem.source,
207
147
  },
148
+ // Because the parent (DocPage) comp need to access it easily
149
+ // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state)
150
+ ...(metadataItem.sidebar && {
151
+ sidebar: metadataItem.sidebar,
152
+ }),
208
153
  };
154
+ return docRoute;
209
155
  }));
210
156
  return routes.sort((a, b) => a.path.localeCompare(b.path));
211
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
+ }
212
198
  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));
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));
214
202
  addRoute({
215
203
  path: loadedVersion.versionPath,
216
204
  // allow matching /docs/* as well
@@ -236,31 +224,36 @@ function pluginContentDocs(context, options) {
236
224
  }
237
225
  await Promise.all(loadedVersions.map(createVersionRoutes));
238
226
  setGlobalData({
239
- path: utils_1.normalizeUrl([baseUrl, options.routeBasePath]),
227
+ path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
240
228
  versions: loadedVersions.map(globalData_1.toGlobalDataVersion),
241
229
  });
242
230
  },
243
- configureWebpack(_config, isServer, utils) {
231
+ configureWebpack(_config, isServer, utils, content) {
244
232
  const { getJSLoader } = utils;
245
233
  const { rehypePlugins, remarkPlugins, beforeDefaultRehypePlugins, beforeDefaultRemarkPlugins, } = options;
234
+ function getSourceToPermalink() {
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);
237
+ }
246
238
  const docsMarkdownOptions = {
247
239
  siteDir,
248
- sourceToPermalink,
240
+ sourceToPermalink: getSourceToPermalink(),
249
241
  versionsMetadata,
250
242
  onBrokenMarkdownLink: (brokenMarkdownLink) => {
251
243
  if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
252
244
  return;
253
245
  }
254
- 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);
255
247
  },
256
248
  };
257
249
  function createMDXLoaderRule() {
250
+ const contentDirs = versionsMetadata.flatMap(versions_1.getDocsDirPaths);
258
251
  return {
259
252
  test: /(\.mdx?)$/,
260
- include: lodash_1.flatten(versionsMetadata.map(versions_1.getDocsDirPaths))
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,11 +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),
266
+ isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
273
267
  metadataPath: (mdxPath) => {
274
268
  // Note that metadataPath must be the same/in-sync as
275
269
  // 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`);
270
+ const aliasedPath = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
271
+ return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedPath)}.json`);
278
272
  },
279
273
  },
280
274
  },
@@ -282,7 +276,7 @@ function pluginContentDocs(context, options) {
282
276
  loader: path_1.default.resolve(__dirname, './markdown/index.js'),
283
277
  options: docsMarkdownOptions,
284
278
  },
285
- ]),
279
+ ].filter(Boolean),
286
280
  };
287
281
  }
288
282
  return {
package/lib/lastUpdate.js CHANGED
@@ -8,8 +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"));
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"));
13
14
  const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+), (.+)$/;
14
15
  let showedGitRequirementError = false;
15
16
  async function getFileLastUpdate(filePath) {
@@ -35,12 +36,11 @@ async function getFileLastUpdate(filePath) {
35
36
  }
36
37
  return null;
37
38
  }
38
- const { stdout } = await execa_1.default('git', [
39
- 'log',
40
- '-1',
41
- '--format=%ct, %an',
42
- filePath,
43
- ]);
39
+ const fileBasename = path_1.default.basename(filePath);
40
+ const fileDirname = path_1.default.dirname(filePath);
41
+ const { stdout } = await (0, execa_1.default)('git', ['log', '-1', '--format=%ct, %an', fileBasename], {
42
+ cwd: fileDirname,
43
+ });
44
44
  return getTimestampAndAuthor(stdout);
45
45
  }
46
46
  catch (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,
package/lib/options.d.ts CHANGED
@@ -9,4 +9,4 @@ import { Joi } from '@docusaurus/utils-validation';
9
9
  import { 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>;