@docusaurus/plugin-content-docs 2.0.0-beta.16 → 2.0.0-beta.19

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 (93) hide show
  1. package/lib/categoryGeneratedIndex.d.ts +1 -1
  2. package/lib/categoryGeneratedIndex.js +5 -7
  3. package/lib/cli.d.ts +3 -2
  4. package/lib/cli.js +49 -41
  5. package/lib/client/docsClientUtils.d.ts +8 -5
  6. package/lib/client/docsClientUtils.js +13 -15
  7. package/lib/client/index.d.ts +12 -9
  8. package/lib/client/index.js +30 -33
  9. package/lib/constants.d.ts +4 -0
  10. package/lib/constants.js +4 -1
  11. package/lib/docs.d.ts +8 -15
  12. package/lib/docs.js +34 -39
  13. package/lib/{docFrontMatter.d.ts → frontMatter.d.ts} +4 -2
  14. package/lib/{docFrontMatter.js → frontMatter.js} +3 -0
  15. package/lib/globalData.d.ts +3 -7
  16. package/lib/globalData.js +9 -13
  17. package/lib/index.d.ts +1 -2
  18. package/lib/index.js +33 -26
  19. package/lib/lastUpdate.d.ts +4 -6
  20. package/lib/lastUpdate.js +14 -5
  21. package/lib/markdown/index.js +1 -1
  22. package/lib/markdown/linkify.js +5 -2
  23. package/lib/numberPrefix.js +16 -22
  24. package/lib/options.d.ts +3 -5
  25. package/lib/options.js +6 -5
  26. package/lib/props.d.ts +3 -3
  27. package/lib/props.js +10 -10
  28. package/lib/routes.d.ts +5 -4
  29. package/lib/routes.js +10 -24
  30. package/lib/server-export.d.ts +2 -1
  31. package/lib/server-export.js +3 -4
  32. package/lib/sidebars/generator.js +63 -44
  33. package/lib/sidebars/index.js +20 -16
  34. package/lib/sidebars/normalization.js +3 -3
  35. package/lib/sidebars/postProcessor.js +18 -25
  36. package/lib/sidebars/processor.d.ts +3 -1
  37. package/lib/sidebars/processor.js +17 -6
  38. package/lib/sidebars/types.d.ts +31 -19
  39. package/lib/sidebars/utils.d.ts +17 -6
  40. package/lib/sidebars/utils.js +27 -37
  41. package/lib/sidebars/validation.d.ts +3 -1
  42. package/lib/sidebars/validation.js +1 -0
  43. package/lib/slug.d.ts +1 -2
  44. package/lib/slug.js +4 -5
  45. package/lib/tags.d.ts +2 -1
  46. package/lib/tags.js +2 -2
  47. package/lib/translations.d.ts +3 -3
  48. package/lib/translations.js +28 -81
  49. package/lib/types.d.ts +10 -95
  50. package/lib/versions/files.d.ts +44 -0
  51. package/lib/versions/files.js +142 -0
  52. package/lib/versions/index.d.ts +36 -0
  53. package/lib/versions/index.js +155 -0
  54. package/lib/versions/validation.d.ts +17 -0
  55. package/lib/versions/validation.js +71 -0
  56. package/package.json +14 -12
  57. package/src/categoryGeneratedIndex.ts +10 -9
  58. package/src/cli.ts +64 -69
  59. package/src/client/docsClientUtils.ts +14 -16
  60. package/src/client/index.ts +42 -43
  61. package/src/constants.ts +4 -2
  62. package/src/deps.d.ts +1 -1
  63. package/src/docs.ts +48 -51
  64. package/src/{docFrontMatter.ts → frontMatter.ts} +9 -6
  65. package/src/globalData.ts +15 -16
  66. package/src/index.ts +45 -40
  67. package/src/lastUpdate.ts +20 -8
  68. package/src/markdown/index.ts +1 -3
  69. package/src/markdown/linkify.ts +6 -3
  70. package/src/numberPrefix.ts +18 -28
  71. package/src/options.ts +6 -8
  72. package/src/plugin-content-docs.d.ts +457 -116
  73. package/src/props.ts +12 -9
  74. package/src/routes.ts +13 -39
  75. package/src/server-export.ts +1 -3
  76. package/src/sidebars/generator.ts +88 -59
  77. package/src/sidebars/index.ts +20 -15
  78. package/src/sidebars/normalization.ts +1 -1
  79. package/src/sidebars/postProcessor.ts +6 -11
  80. package/src/sidebars/processor.ts +27 -14
  81. package/src/sidebars/types.ts +25 -23
  82. package/src/sidebars/utils.ts +45 -46
  83. package/src/sidebars/validation.ts +4 -3
  84. package/src/slug.ts +7 -6
  85. package/src/tags.ts +3 -2
  86. package/src/translations.ts +32 -84
  87. package/src/types.ts +15 -107
  88. package/src/versions/files.ts +220 -0
  89. package/src/versions/index.ts +247 -0
  90. package/src/versions/validation.ts +113 -0
  91. package/lib/versions.d.ts +0 -41
  92. package/lib/versions.js +0 -329
  93. package/src/versions.ts +0 -606
package/lib/docs.js CHANGED
@@ -6,18 +6,17 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.createDocsByIdIndex = exports.getDocIds = exports.splitPath = exports.toCategoryIndexMatcherParam = exports.isCategoryIndex = exports.getMainDocId = exports.addDocNavigation = exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
9
+ exports.createDocsByIdIndex = exports.getDocIds = exports.toCategoryIndexMatcherParam = exports.isCategoryIndex = exports.getMainDocId = exports.addDocNavigation = exports.processDocMetadata = exports.readVersionDocs = exports.readDocFile = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
12
- const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
13
- const logger_1 = (0, tslib_1.__importDefault)(require("@docusaurus/logger"));
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
13
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
14
  const utils_1 = require("@docusaurus/utils");
15
15
  const lastUpdate_1 = require("./lastUpdate");
16
- const slug_1 = (0, tslib_1.__importDefault)(require("./slug"));
16
+ const slug_1 = tslib_1.__importDefault(require("./slug"));
17
17
  const constants_1 = require("./constants");
18
- const versions_1 = require("./versions");
19
18
  const numberPrefix_1 = require("./numberPrefix");
20
- const docFrontMatter_1 = require("./docFrontMatter");
19
+ const frontMatter_1 = require("./frontMatter");
21
20
  const utils_2 = require("./sidebars/utils");
22
21
  async function readLastUpdateData(filePath, options) {
23
22
  const { showLastUpdateAuthor, showLastUpdateTime } = options;
@@ -40,7 +39,7 @@ async function readLastUpdateData(filePath, options) {
40
39
  return {};
41
40
  }
42
41
  async function readDocFile(versionMetadata, source, options) {
43
- const contentPath = await (0, utils_1.getFolderContainingFile)((0, versions_1.getDocsDirPaths)(versionMetadata), source);
42
+ const contentPath = await (0, utils_1.getFolderContainingFile)((0, utils_1.getContentPathList)(versionMetadata), source);
44
43
  const filePath = path_1.default.join(contentPath, source);
45
44
  const [content, lastUpdate] = await Promise.all([
46
45
  fs_extra_1.default.readFile(filePath, 'utf-8'),
@@ -57,33 +56,34 @@ async function readVersionDocs(versionMetadata, options) {
57
56
  return Promise.all(sources.map((source) => readDocFile(versionMetadata, source, options)));
58
57
  }
59
58
  exports.readVersionDocs = readVersionDocs;
60
- function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
61
- var _a, _b, _c, _d, _e, _f;
59
+ /** Docs with draft front matter are only considered draft in production. */
60
+ function isDraftForEnvironment({ env, frontMatter, }) {
61
+ return (env === 'production' && frontMatter.draft) ?? false;
62
+ }
63
+ function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, }) {
62
64
  const { source, content, lastUpdate, contentPath, filePath } = docFile;
63
65
  const { siteDir, i18n } = context;
64
66
  const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = (0, utils_1.parseMarkdownString)(content);
65
- const frontMatter = (0, docFrontMatter_1.validateDocFrontMatter)(unsafeFrontMatter);
67
+ const frontMatter = (0, frontMatter_1.validateDocFrontMatter)(unsafeFrontMatter);
66
68
  const { custom_edit_url: customEditURL,
67
69
  // Strip number prefixes by default
68
70
  // (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
69
71
  // but allow to disable this behavior with front matter
70
72
  parse_number_prefixes: parseNumberPrefixes = true, } = frontMatter;
71
- // ex: api/plugins/myDoc -> myDoc
72
- // ex: myDoc -> myDoc
73
+ // E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
73
74
  const sourceFileNameWithoutExtension = path_1.default.basename(source, path_1.default.extname(source));
74
- // ex: api/plugins/myDoc -> api/plugins
75
- // ex: myDoc -> .
75
+ // E.g. api/plugins/myDoc -> api/plugins; myDoc -> .
76
76
  const sourceDirName = path_1.default.dirname(source);
77
77
  const { filename: unprefixedFileName, numberPrefix } = parseNumberPrefixes
78
78
  ? options.numberPrefixParser(sourceFileNameWithoutExtension)
79
79
  : { filename: sourceFileNameWithoutExtension, numberPrefix: undefined };
80
- const baseID = (_a = frontMatter.id) !== null && _a !== void 0 ? _a : unprefixedFileName;
80
+ const baseID = frontMatter.id ?? unprefixedFileName;
81
81
  if (baseID.includes('/')) {
82
82
  throw new Error(`Document id "${baseID}" cannot include slash.`);
83
83
  }
84
84
  // For autogenerated sidebars, sidebar position can come from filename number
85
85
  // prefix or front matter
86
- const sidebarPosition = (_b = frontMatter.sidebar_position) !== null && _b !== void 0 ? _b : numberPrefix;
86
+ const sidebarPosition = frontMatter.sidebar_position ?? numberPrefix;
87
87
  // TODO legacy retrocompatibility
88
88
  // The same doc in 2 distinct version could keep the same id,
89
89
  // we just need to namespace the data by version
@@ -118,9 +118,9 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
118
118
  // Note: the title is used by default for page title, sidebar label,
119
119
  // pagination buttons... frontMatter.title should be used in priority over
120
120
  // contentTitle (because it can contain markdown/JSX syntax)
121
- const title = (_d = (_c = frontMatter.title) !== null && _c !== void 0 ? _c : contentTitle) !== null && _d !== void 0 ? _d : baseID;
122
- const description = (_f = (_e = frontMatter.description) !== null && _e !== void 0 ? _e : excerpt) !== null && _f !== void 0 ? _f : '';
123
- const permalink = (0, utils_1.normalizeUrl)([versionMetadata.versionPath, docSlug]);
121
+ const title = frontMatter.title ?? contentTitle ?? baseID;
122
+ const description = frontMatter.description ?? excerpt ?? '';
123
+ const permalink = (0, utils_1.normalizeUrl)([versionMetadata.path, docSlug]);
124
124
  function getDocEditUrl() {
125
125
  const relativeFilePath = path_1.default.relative(contentPath, filePath);
126
126
  if (typeof options.editUrl === 'function') {
@@ -135,12 +135,13 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
135
135
  else if (typeof options.editUrl === 'string') {
136
136
  const isLocalized = contentPath === versionMetadata.contentPathLocalized;
137
137
  const baseVersionEditUrl = isLocalized && options.editLocalizedFiles
138
- ? versionMetadata.versionEditUrlLocalized
139
- : versionMetadata.versionEditUrl;
138
+ ? versionMetadata.editUrlLocalized
139
+ : versionMetadata.editUrl;
140
140
  return (0, utils_1.getEditUrl)(relativeFilePath, baseVersionEditUrl);
141
141
  }
142
142
  return undefined;
143
143
  }
144
+ const draft = isDraftForEnvironment({ env, frontMatter });
144
145
  // Assign all of object properties during instantiation (if possible) for
145
146
  // NodeJS optimization.
146
147
  // Adding properties to object after instantiation will cause hidden
@@ -154,13 +155,16 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, }) {
154
155
  sourceDirName,
155
156
  slug: docSlug,
156
157
  permalink,
158
+ draft,
157
159
  editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
158
160
  tags: (0, utils_1.normalizeFrontMatterTags)(versionMetadata.tagsPath, frontMatter.tags),
159
161
  version: versionMetadata.versionName,
160
162
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
161
163
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
162
164
  formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
163
- ? new Intl.DateTimeFormat(i18n.currentLocale).format(lastUpdate.lastUpdatedAt * 1000)
165
+ ? new Intl.DateTimeFormat(i18n.currentLocale, {
166
+ calendar: i18n.localeConfigs[i18n.currentLocale].calendar,
167
+ }).format(lastUpdate.lastUpdatedAt * 1000)
164
168
  : undefined,
165
169
  sidebarPosition,
166
170
  frontMatter,
@@ -202,7 +206,7 @@ function addDocNavigation(docsBase, sidebarsUtils, sidebarFilePath) {
202
206
  return { ...doc, sidebar: navigation.sidebarName, previous, next };
203
207
  }
204
208
  const docsWithNavigation = docsBase.map(addNavData);
205
- // sort to ensure consistent output for tests
209
+ // Sort to ensure consistent output for tests
206
210
  docsWithNavigation.sort((a, b) => a.id.localeCompare(b.id));
207
211
  return docsWithNavigation;
208
212
  }
@@ -241,15 +245,18 @@ exports.getMainDocId = getMainDocId;
241
245
  // - Slugs do not end with a weird "/index" suffix
242
246
  // - Auto-generated sidebar categories link to them as intro
243
247
  const isCategoryIndex = ({ fileName, directories, }) => {
244
- var _a;
245
248
  const eligibleDocIndexNames = [
246
249
  'index',
247
250
  'readme',
248
- (_a = directories[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase(),
251
+ directories[0]?.toLowerCase(),
249
252
  ];
250
253
  return eligibleDocIndexNames.includes(fileName.toLowerCase());
251
254
  };
252
255
  exports.isCategoryIndex = isCategoryIndex;
256
+ /**
257
+ * `guides/sidebar/autogenerated.md` ->
258
+ * `'autogenerated', '.md', ['sidebar', 'guides']`
259
+ */
253
260
  function toCategoryIndexMatcherParam({ source, sourceDirName, }) {
254
261
  // source + sourceDirName are always posix-style
255
262
  return {
@@ -259,18 +266,6 @@ function toCategoryIndexMatcherParam({ source, sourceDirName, }) {
259
266
  };
260
267
  }
261
268
  exports.toCategoryIndexMatcherParam = toCategoryIndexMatcherParam;
262
- /**
263
- * `guides/sidebar/autogenerated.md` ->
264
- * `'autogenerated', '.md', ['sidebar', 'guides']`
265
- */
266
- function splitPath(str) {
267
- return {
268
- fileName: path_1.default.parse(str).name,
269
- extension: path_1.default.parse(str).ext,
270
- directories: path_1.default.dirname(str).split(path_1.default.sep).reverse(),
271
- };
272
- }
273
- exports.splitPath = splitPath;
274
269
  // Return both doc ids
275
270
  // TODO legacy retro-compatibility due to old versioned sidebars using
276
271
  // versioned doc ids ("id" should be removed & "versionedId" should be renamed
@@ -279,7 +274,7 @@ function getDocIds(doc) {
279
274
  return [doc.unversionedId, doc.id];
280
275
  }
281
276
  exports.getDocIds = getDocIds;
282
- // docs are indexed by both versioned and unversioned ids at the same time
277
+ // Docs are indexed by both versioned and unversioned ids at the same time
283
278
  // TODO legacy retro-compatibility due to old versioned sidebars using
284
279
  // versioned doc ids ("id" should be removed & "versionedId" should be renamed
285
280
  // to "id")
@@ -4,5 +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 type { DocFrontMatter } from './types';
8
- export declare function validateDocFrontMatter(frontMatter: Record<string, unknown>): DocFrontMatter;
7
+ import type { DocFrontMatter } from '@docusaurus/plugin-content-docs';
8
+ export declare function validateDocFrontMatter(frontMatter: {
9
+ [key: string]: unknown;
10
+ }): DocFrontMatter;
@@ -14,11 +14,13 @@ const utils_validation_1 = require("@docusaurus/utils-validation");
14
14
  // We use default values in code instead
15
15
  const DocFrontMatterSchema = utils_validation_1.JoiFrontMatter.object({
16
16
  id: utils_validation_1.JoiFrontMatter.string(),
17
+ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
17
18
  title: utils_validation_1.JoiFrontMatter.string().allow(''),
18
19
  hide_title: utils_validation_1.JoiFrontMatter.boolean(),
19
20
  hide_table_of_contents: utils_validation_1.JoiFrontMatter.boolean(),
20
21
  keywords: utils_validation_1.JoiFrontMatter.array().items(utils_validation_1.JoiFrontMatter.string().required()),
21
22
  image: utils_validation_1.URISchema,
23
+ // See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
22
24
  description: utils_validation_1.JoiFrontMatter.string().allow(''),
23
25
  slug: utils_validation_1.JoiFrontMatter.string(),
24
26
  sidebar_label: utils_validation_1.JoiFrontMatter.string(),
@@ -32,6 +34,7 @@ const DocFrontMatterSchema = utils_validation_1.JoiFrontMatter.object({
32
34
  parse_number_prefixes: utils_validation_1.JoiFrontMatter.boolean(),
33
35
  pagination_next: utils_validation_1.JoiFrontMatter.string().allow(null),
34
36
  pagination_prev: utils_validation_1.JoiFrontMatter.string().allow(null),
37
+ draft: utils_validation_1.JoiFrontMatter.boolean(),
35
38
  ...utils_validation_1.FrontMatterTOCHeadingLevels,
36
39
  }).unknown();
37
40
  function validateDocFrontMatter(frontMatter) {
@@ -4,10 +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
- import type { Sidebars } from './sidebars/types';
8
- import type { CategoryGeneratedIndexMetadata, DocMetadata, LoadedVersion } from './types';
9
- import type { GlobalVersion, GlobalSidebar, GlobalDoc } from '@docusaurus/plugin-content-docs/client';
10
- export declare function toGlobalDataDoc(doc: DocMetadata): GlobalDoc;
11
- export declare function toGlobalDataGeneratedIndex(doc: CategoryGeneratedIndexMetadata): GlobalDoc;
12
- export declare function toGlobalSidebars(sidebars: Sidebars, version: LoadedVersion): Record<string, GlobalSidebar>;
13
- export declare function toGlobalDataVersion(version: LoadedVersion): GlobalVersion;
7
+ import type { FullVersion } from './types';
8
+ import type { GlobalVersion } from '@docusaurus/plugin-content-docs/client';
9
+ export declare function toGlobalDataVersion(version: FullVersion): GlobalVersion;
package/lib/globalData.js CHANGED
@@ -6,11 +6,10 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.toGlobalDataVersion = exports.toGlobalSidebars = exports.toGlobalDataGeneratedIndex = exports.toGlobalDataDoc = void 0;
9
+ exports.toGlobalDataVersion = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const lodash_1 = (0, tslib_1.__importDefault)(require("lodash"));
12
- const utils_1 = require("@docusaurus/utils");
13
- const utils_2 = require("./sidebars/utils");
11
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
+ const docs_1 = require("./docs");
14
13
  function toGlobalDataDoc(doc) {
15
14
  return {
16
15
  id: doc.unversionedId,
@@ -18,7 +17,6 @@ function toGlobalDataDoc(doc) {
18
17
  sidebar: doc.sidebar,
19
18
  };
20
19
  }
21
- exports.toGlobalDataDoc = toGlobalDataDoc;
22
20
  function toGlobalDataGeneratedIndex(doc) {
23
21
  return {
24
22
  id: doc.slug,
@@ -26,35 +24,33 @@ function toGlobalDataGeneratedIndex(doc) {
26
24
  sidebar: doc.sidebar,
27
25
  };
28
26
  }
29
- exports.toGlobalDataGeneratedIndex = toGlobalDataGeneratedIndex;
30
27
  function toGlobalSidebars(sidebars, version) {
31
- const { getFirstLink } = (0, utils_2.createSidebarsUtils)(sidebars);
32
28
  return lodash_1.default.mapValues(sidebars, (sidebar, sidebarId) => {
33
- const firstLink = getFirstLink(sidebarId);
29
+ const firstLink = version.sidebarsUtils.getFirstLink(sidebarId);
34
30
  if (!firstLink) {
35
31
  return {};
36
32
  }
37
33
  return {
38
34
  link: {
39
35
  path: firstLink.type === 'generated-index'
40
- ? (0, utils_1.normalizeUrl)([version.versionPath, firstLink.slug])
36
+ ? firstLink.permalink
41
37
  : version.docs.find((doc) => doc.id === firstLink.id || doc.unversionedId === firstLink.id).permalink,
42
38
  label: firstLink.label,
43
39
  },
44
40
  };
45
41
  });
46
42
  }
47
- exports.toGlobalSidebars = toGlobalSidebars;
48
43
  function toGlobalDataVersion(version) {
49
44
  return {
50
45
  name: version.versionName,
51
- label: version.versionLabel,
46
+ label: version.label,
52
47
  isLast: version.isLast,
53
- path: version.versionPath,
54
- mainDocId: version.mainDocId,
48
+ path: version.path,
49
+ mainDocId: (0, docs_1.getMainDocId)(version),
55
50
  docs: version.docs
56
51
  .map(toGlobalDataDoc)
57
52
  .concat(version.categoryGeneratedIndices.map(toGlobalDataGeneratedIndex)),
53
+ draftIds: version.drafts.map((doc) => doc.unversionedId),
58
54
  sidebars: toGlobalSidebars(version.sidebars, version),
59
55
  };
60
56
  }
package/lib/index.d.ts CHANGED
@@ -5,7 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, Plugin } from '@docusaurus/types';
8
- import type { LoadedContent } from './types';
9
- import type { PluginOptions } from '@docusaurus/plugin-content-docs';
8
+ import type { PluginOptions, LoadedContent } from '@docusaurus/plugin-content-docs';
10
9
  export default function pluginContentDocs(context: LoadContext, options: PluginOptions): Promise<Plugin<LoadedContent>>;
11
10
  export { validateOptions } from './options';
package/lib/index.js CHANGED
@@ -8,7 +8,7 @@
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 = (0, tslib_1.__importDefault)(require("path"));
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
12
  const utils_1 = require("@docusaurus/utils");
13
13
  const sidebars_1 = require("./sidebars");
14
14
  const generator_1 = require("./sidebars/generator");
@@ -18,17 +18,19 @@ const cli_1 = require("./cli");
18
18
  const constants_1 = require("./constants");
19
19
  const globalData_1 = require("./globalData");
20
20
  const props_1 = require("./props");
21
+ const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
21
22
  const translations_1 = require("./translations");
22
- const logger_1 = (0, tslib_1.__importDefault)(require("@docusaurus/logger"));
23
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
23
24
  const tags_1 = require("./tags");
24
25
  const routes_1 = require("./routes");
25
26
  const utils_2 = require("./sidebars/utils");
26
- const categoryGeneratedIndex_1 = require("./categoryGeneratedIndex");
27
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
27
28
  async function pluginContentDocs(context, options) {
28
- var _a;
29
29
  const { siteDir, generatedFilesDir, baseUrl, siteConfig } = context;
30
+ // Mutate options to resolve sidebar path according to siteDir
31
+ options.sidebarPath = (0, sidebars_1.resolveSidebarPathOption)(siteDir, options.sidebarPath);
30
32
  const versionsMetadata = await (0, versions_1.readVersionsMetadata)({ context, options });
31
- const pluginId = (_a = options.id) !== null && _a !== void 0 ? _a : utils_1.DEFAULT_PLUGIN_ID;
33
+ const pluginId = options.id;
32
34
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-docs');
33
35
  const dataDir = path_1.default.join(pluginDataDirRoot, pluginId);
34
36
  const aliasedSource = (source) => `~docs/${(0, utils_1.posixPath)(path_1.default.relative(pluginDataDirRoot, source))}`;
@@ -49,21 +51,16 @@ async function pluginContentDocs(context, options) {
49
51
  .arguments('<version>')
50
52
  .description(commandDescription)
51
53
  .action((version) => {
52
- (0, cli_1.cliDocsVersionCommand)(version, siteDir, pluginId, {
53
- path: options.path,
54
- sidebarPath: options.sidebarPath,
55
- sidebarCollapsed: options.sidebarCollapsed,
56
- sidebarCollapsible: options.sidebarCollapsible,
57
- });
54
+ (0, cli_1.cliDocsVersionCommand)(version, options, context);
58
55
  });
59
56
  },
60
- async getTranslationFiles({ content }) {
57
+ getTranslationFiles({ content }) {
61
58
  return (0, translations_1.getLoadedContentTranslationFiles)(content);
62
59
  },
63
60
  getPathsToWatch() {
64
61
  function getVersionPathsToWatch(version) {
65
62
  const result = [
66
- ...options.include.flatMap((pattern) => (0, versions_1.getDocsDirPaths)(version).map((docsDirPath) => `${docsDirPath}/${pattern}`)),
63
+ ...options.include.flatMap((pattern) => (0, utils_1.getContentPathList)(version).map((docsDirPath) => `${docsDirPath}/${pattern}`)),
67
64
  `${version.contentPath}/**/${generator_1.CategoryMetadataFilenamePattern}`,
68
65
  ];
69
66
  if (typeof version.sidebarFilePath === 'string') {
@@ -85,16 +82,19 @@ async function pluginContentDocs(context, options) {
85
82
  versionMetadata,
86
83
  context,
87
84
  options,
85
+ env: process.env.NODE_ENV,
88
86
  });
89
87
  }
90
88
  return Promise.all(docFiles.map(processVersionDoc));
91
89
  }
92
90
  async function doLoadVersion(versionMetadata) {
93
- const docs = await loadVersionDocsBase(versionMetadata);
91
+ const docsBase = await loadVersionDocsBase(versionMetadata);
92
+ const [drafts, docs] = lodash_1.default.partition(docsBase, (doc) => doc.draft);
94
93
  const sidebars = await (0, sidebars_1.loadSidebars)(versionMetadata.sidebarFilePath, {
95
94
  sidebarItemsGenerator: options.sidebarItemsGenerator,
96
95
  numberPrefixParser: options.numberPrefixParser,
97
96
  docs,
97
+ drafts,
98
98
  version: versionMetadata,
99
99
  sidebarOptions: {
100
100
  sidebarCollapsed: options.sidebarCollapsed,
@@ -106,12 +106,8 @@ async function pluginContentDocs(context, options) {
106
106
  return {
107
107
  ...versionMetadata,
108
108
  docs: (0, docs_1.addDocNavigation)(docs, sidebarsUtils, versionMetadata.sidebarFilePath),
109
+ drafts,
109
110
  sidebars,
110
- mainDocId: (0, docs_1.getMainDocId)({ docs, sidebarsUtils }),
111
- categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
112
- docs,
113
- sidebarsUtils,
114
- }),
115
111
  };
116
112
  }
117
113
  async function loadVersion(versionMetadata) {
@@ -134,17 +130,28 @@ async function pluginContentDocs(context, options) {
134
130
  const { loadedVersions } = content;
135
131
  const { docLayoutComponent, docItemComponent, docCategoryGeneratedIndexComponent, breadcrumbs, } = options;
136
132
  const { addRoute, createData, setGlobalData } = actions;
133
+ const versions = loadedVersions.map((version) => {
134
+ const sidebarsUtils = (0, utils_2.createSidebarsUtils)(version.sidebars);
135
+ return {
136
+ ...version,
137
+ sidebarsUtils,
138
+ categoryGeneratedIndices: (0, categoryGeneratedIndex_1.getCategoryGeneratedIndexMetadataList)({
139
+ docs: version.docs,
140
+ sidebarsUtils,
141
+ }),
142
+ };
143
+ });
137
144
  async function createVersionTagsRoutes(version) {
138
145
  const versionTags = (0, tags_1.getVersionTags)(version.docs);
139
146
  // TODO tags should be a sub route of the version route
140
147
  async function createTagsListPage() {
141
148
  const tagsProp = Object.values(versionTags).map((tagValue) => ({
142
- name: tagValue.name,
149
+ label: tagValue.label,
143
150
  permalink: tagValue.permalink,
144
151
  count: tagValue.docIds.length,
145
152
  }));
146
153
  // Only create /tags page if there are tags.
147
- if (Object.keys(tagsProp).length > 0) {
154
+ if (tagsProp.length > 0) {
148
155
  const tagsPropPath = await createData(`${(0, utils_1.docuHash)(`tags-list-${version.versionName}-prop`)}.json`, JSON.stringify(tagsProp, null, 2));
149
156
  addRoute({
150
157
  path: version.tagsPath,
@@ -176,8 +183,8 @@ async function pluginContentDocs(context, options) {
176
183
  await createTagsListPage();
177
184
  await Promise.all(Object.values(versionTags).map(createTagDocListPage));
178
185
  }
179
- await Promise.all(loadedVersions.map((loadedVersion) => (0, routes_1.createVersionRoutes)({
180
- loadedVersion,
186
+ await Promise.all(versions.map((version) => (0, routes_1.createVersionRoutes)({
187
+ version,
181
188
  docItemComponent,
182
189
  docLayoutComponent,
183
190
  docCategoryGeneratedIndexComponent,
@@ -186,10 +193,10 @@ async function pluginContentDocs(context, options) {
186
193
  actions,
187
194
  })));
188
195
  // TODO tags should be a sub route of the version route
189
- await Promise.all(loadedVersions.map(createVersionTagsRoutes));
196
+ await Promise.all(versions.map(createVersionTagsRoutes));
190
197
  setGlobalData({
191
198
  path: (0, utils_1.normalizeUrl)([baseUrl, options.routeBasePath]),
192
- versions: loadedVersions.map(globalData_1.toGlobalDataVersion),
199
+ versions: versions.map(globalData_1.toGlobalDataVersion),
193
200
  breadcrumbs,
194
201
  });
195
202
  },
@@ -212,7 +219,7 @@ async function pluginContentDocs(context, options) {
212
219
  },
213
220
  };
214
221
  function createMDXLoaderRule() {
215
- const contentDirs = versionsMetadata.flatMap(versions_1.getDocsDirPaths);
222
+ const contentDirs = versionsMetadata.flatMap(utils_1.getContentPathList);
216
223
  return {
217
224
  test: /\.mdx?$/i,
218
225
  include: contentDirs
@@ -4,9 +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
- declare type FileLastUpdateData = {
8
- timestamp?: number;
9
- author?: string;
10
- };
11
- export declare function getFileLastUpdate(filePath?: string): Promise<FileLastUpdateData | null>;
12
- export {};
7
+ export declare function getFileLastUpdate(filePath?: string): Promise<{
8
+ timestamp: number;
9
+ author: string;
10
+ } | null>;
package/lib/lastUpdate.js CHANGED
@@ -8,9 +8,10 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.getFileLastUpdate = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const logger_1 = (0, tslib_1.__importDefault)(require("@docusaurus/logger"));
11
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
12
  const utils_1 = require("@docusaurus/utils");
13
13
  let showedGitRequirementError = false;
14
+ let showedFileNotTrackedError = false;
14
15
  async function getFileLastUpdate(filePath) {
15
16
  if (!filePath) {
16
17
  return null;
@@ -25,12 +26,20 @@ async function getFileLastUpdate(filePath) {
25
26
  return { timestamp: result.timestamp, author: result.author };
26
27
  }
27
28
  catch (err) {
28
- if (err instanceof utils_1.GitNotFoundError && !showedGitRequirementError) {
29
- logger_1.default.warn('Sorry, the docs plugin last update options require Git.');
30
- showedGitRequirementError = true;
29
+ if (err instanceof utils_1.GitNotFoundError) {
30
+ if (!showedGitRequirementError) {
31
+ logger_1.default.warn('Sorry, the docs plugin last update options require Git.');
32
+ showedGitRequirementError = true;
33
+ }
34
+ }
35
+ else if (err instanceof utils_1.FileNotTrackedError) {
36
+ if (!showedFileNotTrackedError) {
37
+ logger_1.default.warn('Cannot infer the update date for some files, as they are not tracked by git.');
38
+ showedFileNotTrackedError = true;
39
+ }
31
40
  }
32
41
  else {
33
- logger_1.default.error(err);
42
+ logger_1.default.warn(err);
34
43
  }
35
44
  return null;
36
45
  }
@@ -11,6 +11,6 @@ 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, (0, linkify_1.linkify)(fileString, this.resourcePath, options)));
14
+ return callback?.(null, (0, linkify_1.linkify)(fileString, this.resourcePath, options));
15
15
  }
16
16
  exports.default = markdownLoader;
@@ -7,10 +7,13 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.linkify = void 0;
10
- const versions_1 = require("../versions");
11
10
  const utils_1 = require("@docusaurus/utils");
12
11
  function getVersion(filePath, options) {
13
- const versionFound = options.versionsMetadata.find((version) => (0, versions_1.getDocsDirPaths)(version).some((docsDirPath) => filePath.startsWith(docsDirPath)));
12
+ const versionFound = options.versionsMetadata.find((version) => (0, utils_1.getContentPathList)(version).some((docsDirPath) => filePath.startsWith(docsDirPath)));
13
+ // At this point, this should never happen, because the MDX loaders' paths are
14
+ // literally using the version content paths; but if we allow sourcing content
15
+ // from outside the docs directory (through the `include` option, for example;
16
+ // is there a compelling use-case?), this would actually be testable
14
17
  if (!versionFound) {
15
18
  throw new Error(`Unexpected error: Markdown file at "${filePath}" does not belong to any docs version!`);
16
19
  }
@@ -8,34 +8,28 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.stripPathNumberPrefixes = exports.stripNumberPrefix = exports.DisabledNumberPrefixParser = exports.DefaultNumberPrefixParser = void 0;
10
10
  // Best-effort to avoid parsing some patterns as number prefix
11
- const IgnoredPrefixPatterns = (() => {
12
- // ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640
13
- const DateLikePrefixRegex = /^(?:\d{2}|\d{4})[-_.]\d{2}(?:[-_.](?:\d{2}|\d{4}))?.*$/;
14
- // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
15
- // note: we could try to parse float numbers in filenames but that is
16
- // probably not worth it as a version such as "8.0" can be interpreted as both
17
- // a version and a float. User can configure her own NumberPrefixParser if
18
- // she wants 8.0 to be interpreted as a float
19
- const VersionLikePrefixRegex = /^\d+[-_.]\d+.*$/;
20
- return new RegExp(`${DateLikePrefixRegex.source}|${VersionLikePrefixRegex.source}`);
21
- })();
22
- const NumberPrefixRegex = /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
11
+ // ignore common date-like patterns: https://github.com/facebook/docusaurus/issues/4640
12
+ // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
13
+ // Both of them would look like 7.0-foo or 2021-11-foo
14
+ // note: we could try to parse float numbers in filenames, but that is probably
15
+ // not worth it, as a version such as "8.0" can be interpreted as either a
16
+ // version or a float. User can configure her own NumberPrefixParser if she
17
+ // wants 8.0 to be interpreted as a float
18
+ const ignoredPrefixPattern = /^\d+[-_.]\d+/;
19
+ const numberPrefixPattern = /^(?<numberPrefix>\d+)\s*[-_.]+\s*(?<suffix>[^-_.\s].*)$/;
23
20
  // 0-myDoc => {filename: myDoc, numberPrefix: 0}
24
21
  // 003 - myDoc => {filename: myDoc, numberPrefix: 3}
25
22
  const DefaultNumberPrefixParser = (filename) => {
26
- var _a, _b, _c;
27
- if (IgnoredPrefixPatterns.exec(filename)) {
23
+ if (ignoredPrefixPattern.test(filename)) {
24
+ return { filename, numberPrefix: undefined };
25
+ }
26
+ const match = numberPrefixPattern.exec(filename);
27
+ if (!match) {
28
28
  return { filename, numberPrefix: undefined };
29
29
  }
30
- const match = NumberPrefixRegex.exec(filename);
31
- const cleanFileName = (_b = (_a = match === null || match === void 0 ? void 0 : match.groups) === null || _a === void 0 ? void 0 : _a.suffix) !== null && _b !== void 0 ? _b : filename;
32
- const numberPrefixString = (_c = match === null || match === void 0 ? void 0 : match.groups) === null || _c === void 0 ? void 0 : _c.numberPrefix;
33
- const numberPrefix = numberPrefixString
34
- ? parseInt(numberPrefixString, 10)
35
- : undefined;
36
30
  return {
37
- filename: cleanFileName,
38
- numberPrefix,
31
+ filename: match.groups.suffix,
32
+ numberPrefix: parseInt(match.groups.numberPrefix, 10),
39
33
  };
40
34
  };
41
35
  exports.DefaultNumberPrefixParser = DefaultNumberPrefixParser;
package/lib/options.d.ts CHANGED
@@ -4,9 +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 type { PluginOptions } from '@docusaurus/plugin-content-docs';
8
- import { Joi } from '@docusaurus/utils-validation';
9
- import type { OptionValidationContext, ValidationResult } from '@docusaurus/types';
7
+ import type { PluginOptions, Options } from '@docusaurus/plugin-content-docs';
8
+ import type { OptionValidationContext } from '@docusaurus/types';
10
9
  export declare const DEFAULT_OPTIONS: Omit<PluginOptions, 'id' | 'sidebarPath'>;
11
- export declare const OptionsSchema: Joi.ObjectSchema<any>;
12
- export declare function validateOptions({ validate, options: userOptions, }: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions>;
10
+ export declare function validateOptions({ validate, options: userOptions, }: OptionValidationContext<Options, PluginOptions>): PluginOptions;