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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/categoryGeneratedIndex.d.ts +12 -0
  3. package/lib/categoryGeneratedIndex.js +37 -0
  4. package/lib/cli.d.ts +2 -2
  5. package/lib/cli.js +12 -34
  6. package/lib/client/docsClientUtils.d.ts +1 -4
  7. package/lib/client/docsClientUtils.js +21 -31
  8. package/lib/docFrontMatter.d.ts +1 -1
  9. package/lib/docFrontMatter.js +10 -6
  10. package/lib/docs.d.ts +25 -3
  11. package/lib/docs.js +125 -38
  12. package/lib/globalData.d.ts +1 -1
  13. package/lib/index.d.ts +1 -1
  14. package/lib/index.js +104 -138
  15. package/lib/lastUpdate.js +9 -10
  16. package/lib/markdown/index.d.ts +3 -6
  17. package/lib/markdown/index.js +3 -3
  18. package/lib/markdown/linkify.js +2 -2
  19. package/lib/numberPrefix.d.ts +1 -1
  20. package/lib/options.d.ts +3 -3
  21. package/lib/options.js +49 -17
  22. package/lib/props.d.ts +7 -2
  23. package/lib/props.js +61 -9
  24. package/lib/routes.d.ts +27 -0
  25. package/lib/routes.js +105 -0
  26. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +5 -2
  27. package/lib/sidebars/generator.js +216 -0
  28. package/lib/sidebars/index.d.ts +15 -0
  29. package/lib/sidebars/index.js +73 -0
  30. package/lib/sidebars/normalization.d.ts +14 -0
  31. package/lib/sidebars/normalization.js +77 -0
  32. package/lib/sidebars/processor.d.ts +18 -0
  33. package/lib/sidebars/processor.js +85 -0
  34. package/lib/sidebars/types.d.ts +127 -0
  35. package/lib/sidebars/types.js +8 -0
  36. package/lib/sidebars/utils.d.ts +35 -0
  37. package/lib/sidebars/utils.js +228 -0
  38. package/lib/sidebars/validation.d.ts +10 -0
  39. package/lib/sidebars/validation.js +138 -0
  40. package/lib/slug.d.ts +4 -3
  41. package/lib/slug.js +27 -15
  42. package/lib/tags.d.ts +8 -0
  43. package/lib/tags.js +20 -0
  44. package/lib/theme/hooks/useDocs.js +24 -21
  45. package/lib/translations.d.ts +2 -2
  46. package/lib/translations.js +71 -29
  47. package/lib/types.d.ts +52 -62
  48. package/lib/versions.d.ts +3 -3
  49. package/lib/versions.js +76 -24
  50. package/package.json +22 -20
  51. package/src/__tests__/__fixtures__/simple-site/docs/_partials/somePartial.md +3 -0
  52. package/src/__tests__/__fixtures__/simple-site/docs/_partials/subfolder/somePartial.md +3 -0
  53. package/src/__tests__/__fixtures__/simple-site/docs/_somePartial.md +3 -0
  54. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  55. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +2 -0
  56. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  57. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  58. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  59. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  60. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  61. package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +1 -0
  62. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  63. package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +3 -0
  64. package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  65. package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +3 -0
  66. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +3 -0
  67. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/somePartial.md +3 -0
  68. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_partials/subfolder/somePartial.md +3 -0
  69. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/_somePartial.md +3 -0
  70. package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +3 -0
  71. package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +2 -2
  72. package/src/__tests__/__snapshots__/cli.test.ts.snap +48 -73
  73. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  74. package/src/__tests__/__snapshots__/index.test.ts.snap +753 -112
  75. package/src/__tests__/__snapshots__/translations.test.ts.snap +45 -18
  76. package/src/__tests__/cli.test.ts +15 -11
  77. package/src/__tests__/docFrontMatter.test.ts +195 -40
  78. package/src/__tests__/docs.test.ts +311 -150
  79. package/src/__tests__/index.test.ts +112 -69
  80. package/src/__tests__/lastUpdate.test.ts +3 -2
  81. package/src/__tests__/options.test.ts +48 -4
  82. package/src/__tests__/props.test.ts +62 -0
  83. package/src/__tests__/slug.test.ts +127 -20
  84. package/src/__tests__/translations.test.ts +7 -2
  85. package/src/__tests__/versions.test.ts +93 -67
  86. package/src/categoryGeneratedIndex.ts +57 -0
  87. package/src/cli.ts +8 -41
  88. package/src/client/__tests__/docsClientUtils.test.ts +4 -5
  89. package/src/client/docsClientUtils.ts +19 -41
  90. package/{types.d.ts → src/deps.d.ts} +0 -0
  91. package/src/docFrontMatter.ts +13 -7
  92. package/src/docs.ts +158 -29
  93. package/src/globalData.ts +6 -1
  94. package/src/index.ts +134 -179
  95. package/src/lastUpdate.ts +10 -9
  96. package/src/markdown/index.ts +8 -12
  97. package/src/numberPrefix.ts +5 -3
  98. package/src/options.ts +59 -28
  99. package/src/plugin-content-docs.d.ts +179 -35
  100. package/src/props.ts +91 -16
  101. package/src/routes.ts +173 -0
  102. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  103. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  104. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  105. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  106. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  107. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  108. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  109. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  110. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  111. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  112. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  113. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  114. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  115. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  116. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +36 -6
  117. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +143 -18
  118. package/src/sidebars/__tests__/index.test.ts +204 -0
  119. package/src/sidebars/__tests__/processor.test.ts +237 -0
  120. package/src/sidebars/__tests__/utils.test.ts +695 -0
  121. package/src/sidebars/__tests__/validation.test.ts +105 -0
  122. package/src/sidebars/generator.ts +310 -0
  123. package/src/sidebars/index.ts +94 -0
  124. package/src/sidebars/normalization.ts +112 -0
  125. package/src/sidebars/processor.ts +154 -0
  126. package/src/sidebars/types.ts +211 -0
  127. package/src/sidebars/utils.ts +329 -0
  128. package/src/sidebars/validation.ts +168 -0
  129. package/src/slug.ts +32 -17
  130. package/src/tags.ts +19 -0
  131. package/src/theme/hooks/useDocs.ts +5 -1
  132. package/src/translations.ts +103 -47
  133. package/src/types.ts +67 -105
  134. package/src/versions.ts +117 -21
  135. package/lib/sidebarItemsGenerator.js +0 -211
  136. package/lib/sidebars.d.ts +0 -43
  137. package/lib/sidebars.js +0 -319
  138. package/src/__tests__/sidebars.test.ts +0 -639
  139. package/src/sidebarItemsGenerator.ts +0 -307
  140. package/src/sidebars.ts +0 -506
package/src/index.ts CHANGED
@@ -7,10 +7,6 @@
7
7
 
8
8
  import path from 'path';
9
9
 
10
- import {
11
- STATIC_DIR_NAME,
12
- DEFAULT_PLUGIN_ID,
13
- } from '@docusaurus/core/lib/constants';
14
10
  import {
15
11
  normalizeUrl,
16
12
  docuHash,
@@ -18,10 +14,19 @@ import {
18
14
  reportMessage,
19
15
  posixPath,
20
16
  addTrailingPathSeparator,
17
+ createAbsoluteFilePathMatcher,
18
+ createSlugger,
19
+ DEFAULT_PLUGIN_ID,
21
20
  } from '@docusaurus/utils';
22
- import {LoadContext, Plugin, RouteConfig} from '@docusaurus/types';
23
- import {loadSidebars, createSidebarsUtils, processSidebars} from './sidebars';
24
- import {readVersionDocs, processDocMetadata} from './docs';
21
+ import type {LoadContext, Plugin} from '@docusaurus/types';
22
+ import {loadSidebars} from './sidebars';
23
+ import {CategoryMetadataFilenamePattern} from './sidebars/generator';
24
+ import {
25
+ readVersionDocs,
26
+ processDocMetadata,
27
+ addDocNavigation,
28
+ getMainDocId,
29
+ } from './docs';
25
30
  import {getDocsDirPaths, readVersionsMetadata} from './versions';
26
31
 
27
32
  import {
@@ -29,27 +34,29 @@ import {
29
34
  LoadedContent,
30
35
  SourceToPermalink,
31
36
  DocMetadataBase,
32
- DocMetadata,
33
37
  GlobalPluginData,
34
38
  VersionMetadata,
35
- DocNavLink,
36
39
  LoadedVersion,
37
40
  DocFile,
38
41
  DocsMarkdownOption,
42
+ VersionTag,
39
43
  } from './types';
40
- import {PermalinkToSidebar} from '@docusaurus/plugin-content-docs-types';
41
- import {RuleSetRule} from 'webpack';
44
+ import type {RuleSetRule} from 'webpack';
42
45
  import {cliDocsVersionCommand} from './cli';
43
46
  import {VERSIONS_JSON_FILE} from './constants';
44
- import {flatten, keyBy, compact} from 'lodash';
47
+ import {keyBy, mapValues} from 'lodash';
45
48
  import {toGlobalDataVersion} from './globalData';
46
- import {toVersionMetadataProp} from './props';
49
+ import {toTagDocListProp} from './props';
47
50
  import {
48
51
  translateLoadedContent,
49
52
  getLoadedContentTranslationFiles,
50
53
  } from './translations';
51
- import {CategoryMetadataFilenamePattern} from './sidebarItemsGenerator';
52
54
  import chalk from 'chalk';
55
+ import {getVersionTags} from './tags';
56
+ import {createVersionRoutes} from './routes';
57
+ import type {PropTagsListPage} from '@docusaurus/plugin-content-docs';
58
+ import {createSidebarsUtils} from './sidebars/utils';
59
+ import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
53
60
 
54
61
  export default function pluginContentDocs(
55
62
  context: LoadContext,
@@ -59,7 +66,6 @@ export default function pluginContentDocs(
59
66
 
60
67
  const versionsMetadata = readVersionsMetadata({context, options});
61
68
 
62
- const sourceToPermalink: SourceToPermalink = {};
63
69
  const pluginId = options.id ?? DEFAULT_PLUGIN_ID;
64
70
 
65
71
  const pluginDataDirRoot = path.join(
@@ -101,6 +107,8 @@ export default function pluginContentDocs(
101
107
  cliDocsVersionCommand(version, siteDir, pluginId, {
102
108
  path: options.path,
103
109
  sidebarPath: options.sidebarPath,
110
+ sidebarCollapsed: options.sidebarCollapsed,
111
+ sidebarCollapsible: options.sidebarCollapsible,
104
112
  });
105
113
  });
106
114
  },
@@ -109,22 +117,12 @@ export default function pluginContentDocs(
109
117
  return getLoadedContentTranslationFiles(content);
110
118
  },
111
119
 
112
- getClientModules() {
113
- const modules = [];
114
- if (options.admonitions) {
115
- modules.push(require.resolve('remark-admonitions/styles/infima.css'));
116
- }
117
- return modules;
118
- },
119
-
120
120
  getPathsToWatch() {
121
121
  function getVersionPathsToWatch(version: VersionMetadata): string[] {
122
122
  const result = [
123
- ...flatten(
124
- options.include.map((pattern) =>
125
- getDocsDirPaths(version).map(
126
- (docsDirPath) => `${docsDirPath}/${pattern}`,
127
- ),
123
+ ...options.include.flatMap((pattern) =>
124
+ getDocsDirPaths(version).map(
125
+ (docsDirPath) => `${docsDirPath}/${pattern}`,
128
126
  ),
129
127
  ),
130
128
  `${version.contentPath}/**/${CategoryMetadataFilenamePattern}`,
@@ -135,7 +133,7 @@ export default function pluginContentDocs(
135
133
  return result;
136
134
  }
137
135
 
138
- return flatten(versionsMetadata.map(getVersionPathsToWatch));
136
+ return versionsMetadata.flatMap(getVersionPathsToWatch);
139
137
  },
140
138
 
141
139
  async loadContent() {
@@ -167,104 +165,37 @@ export default function pluginContentDocs(
167
165
  async function doLoadVersion(
168
166
  versionMetadata: VersionMetadata,
169
167
  ): Promise<LoadedVersion> {
170
- const unprocessedSidebars = loadSidebars(
171
- versionMetadata.sidebarFilePath,
172
- );
173
-
174
- const docsBase: DocMetadataBase[] = await loadVersionDocsBase(
168
+ const docs: DocMetadataBase[] = await loadVersionDocsBase(
175
169
  versionMetadata,
176
170
  );
177
- const docsBaseById: Record<string, DocMetadataBase> = keyBy(
178
- docsBase,
179
- (doc) => doc.id,
180
- );
181
171
 
182
- const sidebars = await processSidebars({
172
+ const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
183
173
  sidebarItemsGenerator: options.sidebarItemsGenerator,
184
174
  numberPrefixParser: options.numberPrefixParser,
185
- unprocessedSidebars,
186
- docs: docsBase,
175
+ docs,
187
176
  version: versionMetadata,
177
+ sidebarOptions: {
178
+ sidebarCollapsed: options.sidebarCollapsed,
179
+ sidebarCollapsible: options.sidebarCollapsible,
180
+ },
181
+ categoryLabelSlugger: createSlugger(),
188
182
  });
189
183
 
190
184
  const sidebarsUtils = createSidebarsUtils(sidebars);
191
185
 
192
- const validDocIds = Object.keys(docsBaseById);
193
- sidebarsUtils.checkSidebarsDocIds(
194
- validDocIds,
195
- versionMetadata.sidebarFilePath as string,
196
- );
197
-
198
- // Add sidebar/next/previous to the docs
199
- function addNavData(doc: DocMetadataBase): DocMetadata {
200
- const {
201
- sidebarName,
202
- previousId,
203
- nextId,
204
- } = sidebarsUtils.getDocNavigation(doc.id);
205
- const toDocNavLink = (navDocId: string): DocNavLink => {
206
- const {title, permalink, frontMatter} = docsBaseById[navDocId];
207
- return {
208
- title:
209
- frontMatter.pagination_label ??
210
- frontMatter.sidebar_label ??
211
- title,
212
- permalink,
213
- };
214
- };
215
- return {
216
- ...doc,
217
- sidebar: sidebarName,
218
- previous: previousId ? toDocNavLink(previousId) : undefined,
219
- next: nextId ? toDocNavLink(nextId) : undefined,
220
- };
221
- }
222
-
223
- const docs = docsBase.map(addNavData);
224
-
225
- // sort to ensure consistent output for tests
226
- docs.sort((a, b) => a.id.localeCompare(b.id));
227
-
228
- // TODO annoying side effect!
229
- Object.values(docs).forEach((loadedDoc) => {
230
- const {source, permalink} = loadedDoc;
231
- sourceToPermalink[source] = permalink;
232
- });
233
-
234
- // TODO really useful? replace with global state logic?
235
- const permalinkToSidebar: PermalinkToSidebar = {};
236
- Object.values(docs).forEach((doc) => {
237
- if (doc.sidebar) {
238
- permalinkToSidebar[doc.permalink] = doc.sidebar;
239
- }
240
- });
241
-
242
- // The "main doc" is the "version entry point"
243
- // We browse this doc by clicking on a version:
244
- // - the "home" doc (at '/docs/')
245
- // - the first doc of the first sidebar
246
- // - a random doc (if no docs are in any sidebar... edge case)
247
- function getMainDoc(): DocMetadata {
248
- const versionHomeDoc = docs.find(
249
- (doc) =>
250
- doc.unversionedId === options.homePageId || doc.slug === '/',
251
- );
252
- const firstDocIdOfFirstSidebar = sidebarsUtils.getFirstDocIdOfFirstSidebar();
253
- if (versionHomeDoc) {
254
- return versionHomeDoc;
255
- } else if (firstDocIdOfFirstSidebar) {
256
- return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar)!;
257
- } else {
258
- return docs[0];
259
- }
260
- }
261
-
262
186
  return {
263
187
  ...versionMetadata,
264
- mainDocId: getMainDoc().unversionedId,
188
+ docs: addDocNavigation(
189
+ docs,
190
+ sidebarsUtils,
191
+ versionMetadata.sidebarFilePath as string,
192
+ ),
265
193
  sidebars,
266
- permalinkToSidebar,
267
- docs: docs.map(addNavData),
194
+ mainDocId: getMainDocId({docs, sidebarsUtils}),
195
+ categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({
196
+ docs,
197
+ sidebarsUtils,
198
+ }),
268
199
  };
269
200
  }
270
201
 
@@ -292,76 +223,84 @@ export default function pluginContentDocs(
292
223
 
293
224
  async contentLoaded({content, actions}) {
294
225
  const {loadedVersions} = content;
295
- const {docLayoutComponent, docItemComponent} = options;
226
+ const {
227
+ docLayoutComponent,
228
+ docItemComponent,
229
+ docCategoryGeneratedIndexComponent,
230
+ } = options;
296
231
  const {addRoute, createData, setGlobalData} = actions;
297
232
 
298
- const createDocRoutes = async (
299
- docs: DocMetadata[],
300
- ): Promise<RouteConfig[]> => {
301
- const routes = await Promise.all(
302
- docs.map(async (metadataItem) => {
303
- await createData(
304
- // Note that this created data path must be in sync with
305
- // metadataPath provided to mdx-loader.
306
- `${docuHash(metadataItem.source)}.json`,
307
- JSON.stringify(metadataItem, null, 2),
233
+ async function createVersionTagsRoutes(version: LoadedVersion) {
234
+ const versionTags = getVersionTags(version.docs);
235
+
236
+ // TODO tags should be a sub route of the version route
237
+ async function createTagsListPage() {
238
+ const tagsProp: PropTagsListPage['tags'] = Object.values(
239
+ versionTags,
240
+ ).map((tagValue) => ({
241
+ name: tagValue.name,
242
+ permalink: tagValue.permalink,
243
+ count: tagValue.docIds.length,
244
+ }));
245
+
246
+ // Only create /tags page if there are tags.
247
+ if (Object.keys(tagsProp).length > 0) {
248
+ const tagsPropPath = await createData(
249
+ `${docuHash(`tags-list-${version.versionName}-prop`)}.json`,
250
+ JSON.stringify(tagsProp, null, 2),
308
251
  );
309
-
310
- return {
311
- path: metadataItem.permalink,
312
- component: docItemComponent,
252
+ addRoute({
253
+ path: version.tagsPath,
313
254
  exact: true,
255
+ component: options.docTagsListComponent,
314
256
  modules: {
315
- content: metadataItem.source,
257
+ tags: aliasedSource(tagsPropPath),
316
258
  },
317
- };
318
- }),
319
- );
320
-
321
- return routes.sort((a, b) => a.path.localeCompare(b.path));
322
- };
323
-
324
- async function doCreateVersionRoutes(loadedVersion: LoadedVersion) {
325
- const versionMetadataPropPath = await createData(
326
- `${docuHash(
327
- `version-${loadedVersion.versionName}-metadata-prop`,
328
- )}.json`,
329
- JSON.stringify(
330
- toVersionMetadataProp(pluginId, loadedVersion),
331
- null,
332
- 2,
333
- ),
334
- );
335
-
336
- addRoute({
337
- path: loadedVersion.versionPath,
338
- // allow matching /docs/* as well
339
- exact: false,
340
- // main docs component (DocPage)
341
- component: docLayoutComponent,
342
- // sub-routes for each doc
343
- routes: await createDocRoutes(loadedVersion.docs),
344
- modules: {
345
- versionMetadata: aliasedSource(versionMetadataPropPath),
346
- },
347
- priority: loadedVersion.routePriority,
348
- });
349
- }
259
+ });
260
+ }
261
+ }
350
262
 
351
- async function createVersionRoutes(loadedVersion: LoadedVersion) {
352
- try {
353
- return await doCreateVersionRoutes(loadedVersion);
354
- } catch (e) {
355
- console.error(
356
- chalk.red(
357
- `Can't create version routes for version "${loadedVersion.versionName}"`,
358
- ),
263
+ // TODO tags should be a sub route of the version route
264
+ async function createTagDocListPage(tag: VersionTag) {
265
+ const tagProps = toTagDocListProp({
266
+ allTagsPath: version.tagsPath,
267
+ tag,
268
+ docs: version.docs,
269
+ });
270
+ const tagPropPath = await createData(
271
+ `${docuHash(`tag-${tag.permalink}`)}.json`,
272
+ JSON.stringify(tagProps, null, 2),
359
273
  );
360
- throw e;
274
+ addRoute({
275
+ path: tag.permalink,
276
+ component: options.docTagDocListComponent,
277
+ exact: true,
278
+ modules: {
279
+ tag: aliasedSource(tagPropPath),
280
+ },
281
+ });
361
282
  }
283
+
284
+ await createTagsListPage();
285
+ await Promise.all(Object.values(versionTags).map(createTagDocListPage));
362
286
  }
363
287
 
364
- await Promise.all(loadedVersions.map(createVersionRoutes));
288
+ await Promise.all(
289
+ loadedVersions.map((loadedVersion) =>
290
+ createVersionRoutes({
291
+ loadedVersion,
292
+ docItemComponent,
293
+ docLayoutComponent,
294
+ docCategoryGeneratedIndexComponent,
295
+ pluginId,
296
+ aliasedSource,
297
+ actions,
298
+ }),
299
+ ),
300
+ );
301
+
302
+ // TODO tags should be a sub route of the version route
303
+ await Promise.all(loadedVersions.map(createVersionTagsRoutes));
365
304
 
366
305
  setGlobalData<GlobalPluginData>({
367
306
  path: normalizeUrl([baseUrl, options.routeBasePath]),
@@ -369,7 +308,7 @@ export default function pluginContentDocs(
369
308
  });
370
309
  },
371
310
 
372
- configureWebpack(_config, isServer, utils) {
311
+ configureWebpack(_config, isServer, utils, content) {
373
312
  const {getJSLoader} = utils;
374
313
  const {
375
314
  rehypePlugins,
@@ -378,9 +317,17 @@ export default function pluginContentDocs(
378
317
  beforeDefaultRemarkPlugins,
379
318
  } = options;
380
319
 
320
+ function getSourceToPermalink(): SourceToPermalink {
321
+ const allDocs = content.loadedVersions.flatMap((v) => v.docs);
322
+ return mapValues(
323
+ keyBy(allDocs, (d) => d.source),
324
+ (d) => d.permalink,
325
+ );
326
+ }
327
+
381
328
  const docsMarkdownOptions: DocsMarkdownOption = {
382
329
  siteDir,
383
- sourceToPermalink,
330
+ sourceToPermalink: getSourceToPermalink(),
384
331
  versionsMetadata,
385
332
  onBrokenMarkdownLink: (brokenMarkdownLink) => {
386
333
  if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
@@ -394,12 +341,13 @@ export default function pluginContentDocs(
394
341
  };
395
342
 
396
343
  function createMDXLoaderRule(): RuleSetRule {
344
+ const contentDirs = versionsMetadata.flatMap(getDocsDirPaths);
397
345
  return {
398
346
  test: /(\.mdx?)$/,
399
- include: flatten(versionsMetadata.map(getDocsDirPaths))
347
+ include: contentDirs
400
348
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
401
349
  .map(addTrailingPathSeparator),
402
- use: compact([
350
+ use: [
403
351
  getJSLoader({isServer}),
404
352
  {
405
353
  loader: require.resolve('@docusaurus/mdx-loader'),
@@ -408,7 +356,14 @@ export default function pluginContentDocs(
408
356
  rehypePlugins,
409
357
  beforeDefaultRehypePlugins,
410
358
  beforeDefaultRemarkPlugins,
411
- staticDir: path.join(siteDir, STATIC_DIR_NAME),
359
+ staticDirs: siteConfig.staticDirectories.map((dir) =>
360
+ path.resolve(siteDir, dir),
361
+ ),
362
+ siteDir,
363
+ isMDXPartial: createAbsoluteFilePathMatcher(
364
+ options.exclude,
365
+ contentDirs,
366
+ ),
412
367
  metadataPath: (mdxPath: string) => {
413
368
  // Note that metadataPath must be the same/in-sync as
414
369
  // the path from createData for each MDX.
@@ -421,7 +376,7 @@ export default function pluginContentDocs(
421
376
  loader: path.resolve(__dirname, './markdown/index.js'),
422
377
  options: docsMarkdownOptions,
423
378
  },
424
- ]),
379
+ ].filter(Boolean),
425
380
  };
426
381
  }
427
382
 
package/src/lastUpdate.ts CHANGED
@@ -6,11 +6,10 @@
6
6
  */
7
7
 
8
8
  import shell from 'shelljs';
9
- import execa from 'execa';
10
9
 
11
10
  type FileLastUpdateData = {timestamp?: number; author?: string};
12
11
 
13
- const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+), (.+)$/;
12
+ const GIT_COMMIT_TIMESTAMP_AUTHOR_REGEX = /^(\d+),(.+)$/;
14
13
 
15
14
  let showedGitRequirementError = false;
16
15
 
@@ -43,13 +42,15 @@ export async function getFileLastUpdate(
43
42
  return null;
44
43
  }
45
44
 
46
- const {stdout} = await execa('git', [
47
- 'log',
48
- '-1',
49
- '--format=%ct, %an',
50
- filePath,
51
- ]);
52
- return getTimestampAndAuthor(stdout);
45
+ const result = shell.exec(`git log -1 --format=%ct,%an ${filePath}`, {
46
+ silent: true,
47
+ });
48
+ if (result.code !== 0) {
49
+ throw new Error(
50
+ `Retrieval of git history failed at ${filePath} with exit code ${result.code}: ${result.stderr}`,
51
+ );
52
+ }
53
+ return getTimestampAndAuthor(result.stdout.trim());
53
54
  } catch (error) {
54
55
  console.error(error);
55
56
  }
@@ -7,20 +7,16 @@
7
7
 
8
8
  import {linkify} from './linkify';
9
9
  import {DocsMarkdownOption} from '../types';
10
+ import type {LoaderContext} from 'webpack';
10
11
 
11
- // TODO temporary until Webpack5 export this type
12
- // see https://github.com/webpack/webpack/issues/11630
13
- interface Loader extends Function {
14
- (this: any, source: string): string | Buffer | void | undefined;
15
- }
16
-
17
- const markdownLoader: Loader = function (source) {
18
- const fileString = source as string;
12
+ export default function markdownLoader(
13
+ this: LoaderContext<DocsMarkdownOption>,
14
+ source: string,
15
+ ): void {
16
+ const fileString = source;
19
17
  const callback = this.async();
20
- const options = this.getOptions() as DocsMarkdownOption;
18
+ const options = this.getOptions();
21
19
  return (
22
20
  callback && callback(null, linkify(fileString, this.resourcePath, options))
23
21
  );
24
- };
25
-
26
- export default markdownLoader;
22
+ }
@@ -5,12 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {NumberPrefixParser} from './types';
8
+ import type {NumberPrefixParser} from './types';
9
9
 
10
10
  // Best-effort to avoid parsing some patterns as number prefix
11
11
  const IgnoredPrefixPatterns = (function () {
12
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}))?)(.*)$/;
13
+ const DateLikePrefixRegex =
14
+ /^((\d{2}|\d{4})[-_.]\d{2}([-_.](\d{2}|\d{4}))?)(.*)$/;
14
15
 
15
16
  // ignore common versioning patterns: https://github.com/facebook/docusaurus/issues/4653
16
17
  // note: we could try to parse float numbers in filenames but that is probably not worth it
@@ -23,7 +24,8 @@ const IgnoredPrefixPatterns = (function () {
23
24
  );
24
25
  })();
25
26
 
26
- const NumberPrefixRegex = /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
27
+ const NumberPrefixRegex =
28
+ /^(?<numberPrefix>\d+)(?<separator>\s*[-_.]+\s*)(?<suffix>.*)$/;
27
29
 
28
30
  // 0-myDoc => {filename: myDoc, numberPrefix: 0}
29
31
  // 003 - myDoc => {filename: myDoc, numberPrefix: 3}