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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/cli.d.ts +1 -1
  3. package/lib/cli.js +18 -23
  4. package/lib/client/docsClientUtils.d.ts +0 -3
  5. package/lib/client/docsClientUtils.js +10 -7
  6. package/lib/docFrontMatter.js +6 -2
  7. package/lib/docs.d.ts +3 -1
  8. package/lib/docs.js +76 -25
  9. package/lib/index.js +70 -77
  10. package/lib/lastUpdate.js +4 -4
  11. package/lib/markdown/index.d.ts +3 -6
  12. package/lib/markdown/index.js +3 -3
  13. package/lib/markdown/linkify.js +2 -2
  14. package/lib/options.js +12 -4
  15. package/lib/props.d.ts +7 -2
  16. package/lib/props.js +26 -3
  17. package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +2 -1
  18. package/lib/sidebars/generator.js +174 -0
  19. package/lib/sidebars/index.d.ts +14 -0
  20. package/lib/sidebars/index.js +64 -0
  21. package/lib/sidebars/normalization.d.ts +9 -0
  22. package/lib/sidebars/normalization.js +58 -0
  23. package/lib/sidebars/processor.d.ts +16 -0
  24. package/lib/sidebars/processor.js +70 -0
  25. package/lib/sidebars/types.d.ts +87 -0
  26. package/lib/sidebars/types.js +13 -0
  27. package/lib/sidebars/utils.d.ts +22 -0
  28. package/lib/sidebars/utils.js +101 -0
  29. package/lib/sidebars/validation.d.ts +8 -0
  30. package/lib/sidebars/validation.js +102 -0
  31. package/lib/slug.js +4 -4
  32. package/lib/tags.d.ts +8 -0
  33. package/lib/tags.js +22 -0
  34. package/lib/theme/hooks/useDocs.js +21 -21
  35. package/lib/translations.d.ts +1 -1
  36. package/lib/translations.js +13 -13
  37. package/lib/types.d.ts +29 -61
  38. package/lib/versions.d.ts +1 -1
  39. package/lib/versions.js +40 -20
  40. package/package.json +15 -14
  41. package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +5 -0
  42. package/src/__tests__/__fixtures__/simple-site/docs/hello.md +1 -0
  43. package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +2 -0
  44. package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +2 -0
  45. package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +2 -0
  46. package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +2 -0
  47. package/src/__tests__/__fixtures__/simple-site/sidebars.json +15 -1
  48. package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +6 -0
  49. package/src/__tests__/__snapshots__/cli.test.ts.snap +28 -0
  50. package/src/__tests__/__snapshots__/docs.test.ts.snap +140 -0
  51. package/src/__tests__/__snapshots__/index.test.ts.snap +426 -25
  52. package/src/__tests__/docFrontMatter.test.ts +160 -45
  53. package/src/__tests__/docs.test.ts +167 -21
  54. package/src/__tests__/index.test.ts +53 -27
  55. package/src/__tests__/options.test.ts +4 -1
  56. package/src/__tests__/props.test.ts +62 -0
  57. package/src/__tests__/versions.test.ts +68 -63
  58. package/src/cli.ts +23 -30
  59. package/src/client/docsClientUtils.ts +1 -12
  60. package/src/docFrontMatter.ts +7 -2
  61. package/src/docs.ts +88 -9
  62. package/src/index.ts +77 -91
  63. package/src/markdown/index.ts +8 -12
  64. package/src/numberPrefix.ts +4 -2
  65. package/src/options.ts +13 -1
  66. package/src/plugin-content-docs.d.ts +107 -32
  67. package/src/props.ts +41 -5
  68. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -0
  69. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -0
  70. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -0
  71. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-category.js +0 -0
  72. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -0
  73. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-collapsed.json +0 -0
  74. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -0
  75. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -0
  76. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -0
  77. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -0
  78. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-link.json +0 -0
  79. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-unknown-type.json +0 -0
  80. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars-wrong-field.json +0 -0
  81. package/src/{__tests__ → sidebars/__tests__}/__fixtures__/sidebars/sidebars.json +0 -0
  82. package/src/{__tests__/__snapshots__/sidebars.test.ts.snap → sidebars/__tests__/__snapshots__/index.test.ts.snap} +6 -6
  83. package/src/{__tests__/sidebarItemsGenerator.test.ts → sidebars/__tests__/generator.test.ts} +2 -2
  84. package/src/sidebars/__tests__/index.test.ts +202 -0
  85. package/src/sidebars/__tests__/processor.test.ts +148 -0
  86. package/src/sidebars/__tests__/utils.test.ts +395 -0
  87. package/src/sidebars/generator.ts +253 -0
  88. package/src/sidebars/index.ts +84 -0
  89. package/src/sidebars/normalization.ts +88 -0
  90. package/src/sidebars/processor.ts +124 -0
  91. package/src/sidebars/types.ts +156 -0
  92. package/src/sidebars/utils.ts +146 -0
  93. package/src/sidebars/validation.ts +124 -0
  94. package/src/tags.ts +21 -0
  95. package/src/translations.ts +26 -36
  96. package/src/types.ts +35 -101
  97. package/src/versions.ts +51 -21
  98. package/lib/sidebarItemsGenerator.js +0 -215
  99. package/lib/sidebars.d.ts +0 -45
  100. package/lib/sidebars.js +0 -354
  101. package/src/__tests__/sidebars.test.ts +0 -746
  102. package/src/sidebarItemsGenerator.ts +0 -315
  103. package/src/sidebars.ts +0 -589
@@ -77,10 +77,13 @@ describe('simple site', () => {
77
77
  isLast: true,
78
78
  routePriority: -1,
79
79
  sidebarFilePath: undefined,
80
+ tagsPath: '/docs/tags',
80
81
  versionLabel: 'Next',
81
82
  versionName: 'current',
82
83
  versionPath: '/docs',
83
- versionBanner: 'none',
84
+ versionBanner: null,
85
+ versionBadge: false,
86
+ versionClassName: 'docs-version-current',
84
87
  };
85
88
  return {simpleSiteDir, defaultOptions, defaultContext, vCurrent};
86
89
  }
@@ -111,6 +114,7 @@ describe('simple site', () => {
111
114
  {
112
115
  ...vCurrent,
113
116
  versionPath: '/myBaseUrl/docs',
117
+ tagsPath: '/myBaseUrl/docs/tags',
114
118
  },
115
119
  ]);
116
120
  });
@@ -141,6 +145,7 @@ describe('simple site', () => {
141
145
  versionLabel: 'current-label',
142
146
  routePriority: undefined,
143
147
  sidebarFilePath: undefined,
148
+ tagsPath: '/myBaseUrl/docs/current-path/tags',
144
149
  versionEditUrl: undefined,
145
150
  versionEditUrlLocalized: undefined,
146
151
  },
@@ -232,10 +237,13 @@ describe('versioned site, pluginId=default', () => {
232
237
  isLast: false,
233
238
  routePriority: undefined,
234
239
  sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
240
+ tagsPath: '/docs/next/tags',
235
241
  versionLabel: 'Next',
236
242
  versionName: 'current',
237
243
  versionPath: '/docs/next',
238
244
  versionBanner: 'unreleased',
245
+ versionBadge: true,
246
+ versionClassName: 'docs-version-current',
239
247
  };
240
248
 
241
249
  const v101: VersionMetadata = {
@@ -250,10 +258,13 @@ describe('versioned site, pluginId=default', () => {
250
258
  versionedSiteDir,
251
259
  'versioned_sidebars/version-1.0.1-sidebars.json',
252
260
  ),
261
+ tagsPath: '/docs/tags',
253
262
  versionLabel: '1.0.1',
254
263
  versionName: '1.0.1',
255
264
  versionPath: '/docs',
256
- versionBanner: 'none',
265
+ versionBanner: null,
266
+ versionBadge: true,
267
+ versionClassName: 'docs-version-1.0.1',
257
268
  };
258
269
 
259
270
  const v100: VersionMetadata = {
@@ -268,10 +279,13 @@ describe('versioned site, pluginId=default', () => {
268
279
  versionedSiteDir,
269
280
  'versioned_sidebars/version-1.0.0-sidebars.json',
270
281
  ),
282
+ tagsPath: '/docs/1.0.0/tags',
271
283
  versionLabel: '1.0.0',
272
284
  versionName: '1.0.0',
273
285
  versionPath: '/docs/1.0.0',
274
286
  versionBanner: 'unmaintained',
287
+ versionBadge: true,
288
+ versionClassName: 'docs-version-1.0.0',
275
289
  };
276
290
 
277
291
  const vwithSlugs: VersionMetadata = {
@@ -289,10 +303,13 @@ describe('versioned site, pluginId=default', () => {
289
303
  versionedSiteDir,
290
304
  'versioned_sidebars/version-withSlugs-sidebars.json',
291
305
  ),
306
+ tagsPath: '/docs/withSlugs/tags',
292
307
  versionLabel: 'withSlugs',
293
308
  versionName: 'withSlugs',
294
309
  versionPath: '/docs/withSlugs',
295
310
  versionBanner: 'unmaintained',
311
+ versionBadge: true,
312
+ versionClassName: 'docs-version-withSlugs',
296
313
  };
297
314
 
298
315
  return {
@@ -307,14 +324,8 @@ describe('versioned site, pluginId=default', () => {
307
324
  }
308
325
 
309
326
  test('readVersionsMetadata versioned site', async () => {
310
- const {
311
- defaultOptions,
312
- defaultContext,
313
- vCurrent,
314
- v101,
315
- v100,
316
- vwithSlugs,
317
- } = await loadSite();
327
+ const {defaultOptions, defaultContext, vCurrent, v101, v100, vwithSlugs} =
328
+ await loadSite();
318
329
 
319
330
  const versionsMetadata = readVersionsMetadata({
320
331
  options: defaultOptions,
@@ -325,13 +336,8 @@ describe('versioned site, pluginId=default', () => {
325
336
  });
326
337
 
327
338
  test('readVersionsMetadata versioned site with includeCurrentVersion=false', async () => {
328
- const {
329
- defaultOptions,
330
- defaultContext,
331
- v101,
332
- v100,
333
- vwithSlugs,
334
- } = await loadSite();
339
+ const {defaultOptions, defaultContext, v101, v100, vwithSlugs} =
340
+ await loadSite();
335
341
 
336
342
  const versionsMetadata = readVersionsMetadata({
337
343
  options: {...defaultOptions, includeCurrentVersion: false},
@@ -347,14 +353,8 @@ describe('versioned site, pluginId=default', () => {
347
353
  });
348
354
 
349
355
  test('readVersionsMetadata versioned site with version options', async () => {
350
- const {
351
- defaultOptions,
352
- defaultContext,
353
- vCurrent,
354
- v101,
355
- v100,
356
- vwithSlugs,
357
- } = await loadSite();
356
+ const {defaultOptions, defaultContext, vCurrent, v101, v100, vwithSlugs} =
357
+ await loadSite();
358
358
 
359
359
  const versionsMetadata = readVersionsMetadata({
360
360
  options: {
@@ -364,6 +364,8 @@ describe('versioned site, pluginId=default', () => {
364
364
  current: {
365
365
  path: 'current-path',
366
366
  banner: 'unmaintained',
367
+ badge: false,
368
+ className: 'custom-current-className',
367
369
  },
368
370
  '1.0.0': {
369
371
  label: '1.0.0-label',
@@ -377,13 +379,17 @@ describe('versioned site, pluginId=default', () => {
377
379
  expect(versionsMetadata).toEqual([
378
380
  {
379
381
  ...vCurrent,
382
+ tagsPath: '/docs/current-path/tags',
380
383
  versionPath: '/docs/current-path',
381
384
  versionBanner: 'unmaintained',
385
+ versionBadge: false,
386
+ versionClassName: 'custom-current-className',
382
387
  },
383
388
  {
384
389
  ...v101,
385
390
  isLast: false,
386
391
  routePriority: undefined,
392
+ tagsPath: '/docs/1.0.1/tags',
387
393
  versionPath: '/docs/1.0.1',
388
394
  versionBanner: 'unreleased',
389
395
  },
@@ -391,6 +397,7 @@ describe('versioned site, pluginId=default', () => {
391
397
  ...v100,
392
398
  isLast: true,
393
399
  routePriority: -1,
400
+ tagsPath: '/docs/tags',
394
401
  versionLabel: '1.0.0-label',
395
402
  versionPath: '/docs',
396
403
  versionBanner: 'unreleased',
@@ -400,19 +407,13 @@ describe('versioned site, pluginId=default', () => {
400
407
  });
401
408
 
402
409
  test('readVersionsMetadata versioned site with editUrl', async () => {
403
- const {
404
- defaultOptions,
405
- defaultContext,
406
- vCurrent,
407
- v101,
408
- v100,
409
- vwithSlugs,
410
- } = await loadSite();
410
+ const {defaultOptions, defaultContext, vCurrent, v101, v100, vwithSlugs} =
411
+ await loadSite();
411
412
 
412
413
  const versionsMetadata = readVersionsMetadata({
413
414
  options: {
414
415
  ...defaultOptions,
415
- editUrl: 'https://github.com/facebook/docusaurus/edit/master/website/',
416
+ editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/',
416
417
  },
417
418
  context: defaultContext,
418
419
  });
@@ -421,48 +422,42 @@ describe('versioned site, pluginId=default', () => {
421
422
  {
422
423
  ...vCurrent,
423
424
  versionEditUrl:
424
- 'https://github.com/facebook/docusaurus/edit/master/website/docs',
425
+ 'https://github.com/facebook/docusaurus/edit/main/website/docs',
425
426
  versionEditUrlLocalized:
426
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/current',
427
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/current',
427
428
  },
428
429
  {
429
430
  ...v101,
430
431
  versionEditUrl:
431
- 'https://github.com/facebook/docusaurus/edit/master/website/versioned_docs/version-1.0.1',
432
+ 'https://github.com/facebook/docusaurus/edit/main/website/versioned_docs/version-1.0.1',
432
433
  versionEditUrlLocalized:
433
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/version-1.0.1',
434
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/version-1.0.1',
434
435
  },
435
436
  {
436
437
  ...v100,
437
438
  versionEditUrl:
438
- 'https://github.com/facebook/docusaurus/edit/master/website/versioned_docs/version-1.0.0',
439
+ 'https://github.com/facebook/docusaurus/edit/main/website/versioned_docs/version-1.0.0',
439
440
  versionEditUrlLocalized:
440
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/version-1.0.0',
441
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/version-1.0.0',
441
442
  },
442
443
  {
443
444
  ...vwithSlugs,
444
445
  versionEditUrl:
445
- 'https://github.com/facebook/docusaurus/edit/master/website/versioned_docs/version-withSlugs',
446
+ 'https://github.com/facebook/docusaurus/edit/main/website/versioned_docs/version-withSlugs',
446
447
  versionEditUrlLocalized:
447
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/version-withSlugs',
448
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/version-withSlugs',
448
449
  },
449
450
  ]);
450
451
  });
451
452
 
452
453
  test('readVersionsMetadata versioned site with editUrl and editCurrentVersion=true', async () => {
453
- const {
454
- defaultOptions,
455
- defaultContext,
456
- vCurrent,
457
- v101,
458
- v100,
459
- vwithSlugs,
460
- } = await loadSite();
454
+ const {defaultOptions, defaultContext, vCurrent, v101, v100, vwithSlugs} =
455
+ await loadSite();
461
456
 
462
457
  const versionsMetadata = readVersionsMetadata({
463
458
  options: {
464
459
  ...defaultOptions,
465
- editUrl: 'https://github.com/facebook/docusaurus/edit/master/website/',
460
+ editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/',
466
461
  editCurrentVersion: true,
467
462
  },
468
463
  context: defaultContext,
@@ -472,30 +467,30 @@ describe('versioned site, pluginId=default', () => {
472
467
  {
473
468
  ...vCurrent,
474
469
  versionEditUrl:
475
- 'https://github.com/facebook/docusaurus/edit/master/website/docs',
470
+ 'https://github.com/facebook/docusaurus/edit/main/website/docs',
476
471
  versionEditUrlLocalized:
477
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/current',
472
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/current',
478
473
  },
479
474
  {
480
475
  ...v101,
481
476
  versionEditUrl:
482
- 'https://github.com/facebook/docusaurus/edit/master/website/docs',
477
+ 'https://github.com/facebook/docusaurus/edit/main/website/docs',
483
478
  versionEditUrlLocalized:
484
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/current',
479
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/current',
485
480
  },
486
481
  {
487
482
  ...v100,
488
483
  versionEditUrl:
489
- 'https://github.com/facebook/docusaurus/edit/master/website/docs',
484
+ 'https://github.com/facebook/docusaurus/edit/main/website/docs',
490
485
  versionEditUrlLocalized:
491
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/current',
486
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/current',
492
487
  },
493
488
  {
494
489
  ...vwithSlugs,
495
490
  versionEditUrl:
496
- 'https://github.com/facebook/docusaurus/edit/master/website/docs',
491
+ 'https://github.com/facebook/docusaurus/edit/main/website/docs',
497
492
  versionEditUrlLocalized:
498
- 'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/current',
493
+ 'https://github.com/facebook/docusaurus/edit/main/website/i18n/en/docusaurus-plugin-content-docs/current',
499
494
  },
500
495
  ]);
501
496
  });
@@ -528,8 +523,10 @@ describe('versioned site, pluginId=default', () => {
528
523
  ...vCurrent,
529
524
  isLast: true,
530
525
  routePriority: -1,
526
+ tagsPath: '/docs/tags',
531
527
  versionPath: '/docs',
532
- versionBanner: 'none',
528
+ versionBanner: null,
529
+ versionBadge: false,
533
530
  },
534
531
  ]);
535
532
  });
@@ -648,10 +645,13 @@ describe('versioned site, pluginId=community', () => {
648
645
  isLast: false,
649
646
  routePriority: undefined,
650
647
  sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
648
+ tagsPath: '/communityBasePath/next/tags',
651
649
  versionLabel: 'Next',
652
650
  versionName: 'current',
653
651
  versionPath: '/communityBasePath/next',
654
652
  versionBanner: 'unreleased',
653
+ versionBadge: true,
654
+ versionClassName: 'docs-version-current',
655
655
  };
656
656
 
657
657
  const v100: VersionMetadata = {
@@ -669,10 +669,13 @@ describe('versioned site, pluginId=community', () => {
669
669
  versionedSiteDir,
670
670
  'community_versioned_sidebars/version-1.0.0-sidebars.json',
671
671
  ),
672
+ tagsPath: '/communityBasePath/tags',
672
673
  versionLabel: '1.0.0',
673
674
  versionName: '1.0.0',
674
675
  versionPath: '/communityBasePath',
675
- versionBanner: 'none',
676
+ versionBanner: null,
677
+ versionBadge: true,
678
+ versionClassName: 'docs-version-1.0.0',
676
679
  };
677
680
 
678
681
  return {versionedSiteDir, defaultOptions, defaultContext, vCurrent, v100};
@@ -699,7 +702,7 @@ describe('versioned site, pluginId=community', () => {
699
702
 
700
703
  expect(versionsMetadata).toEqual([
701
704
  // vCurrent removed
702
- v100,
705
+ {...v100, versionBadge: false},
703
706
  ]);
704
707
  });
705
708
 
@@ -716,8 +719,10 @@ describe('versioned site, pluginId=community', () => {
716
719
  ...vCurrent,
717
720
  isLast: true,
718
721
  routePriority: -1,
722
+ tagsPath: '/communityBasePath/tags',
719
723
  versionPath: '/communityBasePath',
720
- versionBanner: 'none',
724
+ versionBanner: null,
725
+ versionBadge: false,
721
726
  },
722
727
  ]);
723
728
  });
package/src/cli.ts CHANGED
@@ -12,13 +12,10 @@ import {
12
12
  } from './versions';
13
13
  import fs from 'fs-extra';
14
14
  import path from 'path';
15
- import {
16
- PathOptions,
17
- UnprocessedSidebarItem,
18
- UnprocessedSidebars,
19
- SidebarOptions,
20
- } from './types';
21
- import {loadSidebars, resolveSidebarPathOption} from './sidebars';
15
+ import type {PathOptions, SidebarOptions} from './types';
16
+ import {transformSidebarItems} from './sidebars/utils';
17
+ import type {SidebarItem, NormalizedSidebars, Sidebar} from './sidebars/types';
18
+ import {loadUnprocessedSidebars, resolveSidebarPathOption} from './sidebars';
22
19
  import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
23
20
 
24
21
  function createVersionedSidebarFile({
@@ -35,7 +32,7 @@ function createVersionedSidebarFile({
35
32
  options: SidebarOptions;
36
33
  }) {
37
34
  // Load current sidebar and create a new versioned sidebars file (if needed).
38
- const loadedSidebars = loadSidebars(sidebarPath, options);
35
+ const loadedSidebars = loadUnprocessedSidebars(sidebarPath, options);
39
36
 
40
37
  // Do not create a useless versioned sidebars file if sidebars file is empty or sidebars are disabled/false)
41
38
  const shouldCreateVersionedSidebarFile =
@@ -45,30 +42,27 @@ function createVersionedSidebarFile({
45
42
  // TODO @slorber: this "version prefix" in versioned sidebars looks like a bad idea to me
46
43
  // TODO try to get rid of it
47
44
  // Transform id in original sidebar to versioned id.
48
- const normalizeItem = (
49
- item: UnprocessedSidebarItem,
50
- ): UnprocessedSidebarItem => {
51
- switch (item.type) {
52
- case 'category':
53
- return {...item, items: item.items.map(normalizeItem)};
54
- case 'ref':
55
- case 'doc':
56
- return {
57
- type: item.type,
58
- id: `version-${version}/${item.id}`,
59
- };
60
- default:
61
- return item;
45
+ const prependVersion = (item: SidebarItem): SidebarItem => {
46
+ if (item.type === 'ref' || item.type === 'doc') {
47
+ return {
48
+ type: item.type,
49
+ id: `version-${version}/${item.id}`,
50
+ };
62
51
  }
52
+ return item;
63
53
  };
64
54
 
65
- const versionedSidebar: UnprocessedSidebars = Object.entries(
66
- loadedSidebars,
67
- ).reduce((acc: UnprocessedSidebars, [sidebarId, sidebarItems]) => {
68
- const newVersionedSidebarId = `version-${version}/${sidebarId}`;
69
- acc[newVersionedSidebarId] = sidebarItems.map(normalizeItem);
70
- return acc;
71
- }, {});
55
+ const versionedSidebar = Object.entries(loadedSidebars).reduce(
56
+ (acc: NormalizedSidebars, [sidebarId, sidebar]) => {
57
+ const versionedId = `version-${version}/${sidebarId}`;
58
+ acc[versionedId] = transformSidebarItems(
59
+ sidebar as Sidebar,
60
+ prependVersion,
61
+ );
62
+ return acc;
63
+ },
64
+ {},
65
+ );
72
66
 
73
67
  const versionedSidebarsDir = getVersionedSidebarsDirPath(siteDir, pluginId);
74
68
  const newSidebarFile = path.join(
@@ -85,7 +79,6 @@ function createVersionedSidebarFile({
85
79
  }
86
80
 
87
81
  // Tests depend on non-default export for mocking.
88
- // eslint-disable-next-line import/prefer-default-export
89
82
  export function cliDocsVersionCommand(
90
83
  version: string | null | undefined,
91
84
  siteDir: string,
@@ -20,22 +20,11 @@ export type ActivePlugin = {
20
20
  pluginData: GlobalPluginData;
21
21
  };
22
22
 
23
- export type GetActivePluginOptions = {failfast?: boolean};
23
+ export type GetActivePluginOptions = {failfast?: boolean}; // use fail-fast option if you know for sure one plugin instance is active
24
24
 
25
25
  // get the data of the plugin that is currently "active"
26
26
  // ie the docs of that plugin are currently browsed
27
27
  // it is useful to support multiple docs plugin instances
28
- export function getActivePlugin(
29
- allPluginDatas: Record<string, GlobalPluginData>,
30
- pathname: string,
31
- options: {failfast: true}, // use fail-fast option if you know for sure one plugin instance is active
32
- ): ActivePlugin;
33
- export function getActivePlugin(
34
- allPluginDatas: Record<string, GlobalPluginData>,
35
- pathname: string,
36
- options?: GetActivePluginOptions,
37
- ): ActivePlugin | undefined;
38
-
39
28
  export function getActivePlugin(
40
29
  allPluginDatas: Record<string, GlobalPluginData>,
41
30
  pathname: string,
@@ -5,11 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- /* eslint-disable camelcase */
9
-
10
8
  import {
11
9
  JoiFrontMatter as Joi, // Custom instance for frontmatter
12
10
  URISchema,
11
+ FrontMatterTagsSchema,
12
+ FrontMatterTOCHeadingLevels,
13
13
  validateFrontMatter,
14
14
  } from '@docusaurus/utils-validation';
15
15
  import {DocFrontMatter} from './types';
@@ -29,9 +29,14 @@ const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
29
29
  slug: Joi.string(),
30
30
  sidebar_label: Joi.string(),
31
31
  sidebar_position: Joi.number(),
32
+ sidebar_class_name: Joi.string(),
33
+ tags: FrontMatterTagsSchema,
32
34
  pagination_label: Joi.string(),
33
35
  custom_edit_url: URISchema.allow('', null),
34
36
  parse_number_prefixes: Joi.boolean(),
37
+ pagination_next: Joi.string().allow(null),
38
+ pagination_prev: Joi.string().allow(null),
39
+ ...FrontMatterTOCHeadingLevels,
35
40
  }).unknown();
36
41
 
37
42
  export function validateDocFrontMatter(
package/src/docs.ts CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  import path from 'path';
9
9
  import fs from 'fs-extra';
10
+ import chalk from 'chalk';
11
+ import {keyBy} from 'lodash';
10
12
  import {
11
13
  aliasedSitePath,
12
14
  getEditUrl,
@@ -15,6 +17,7 @@ import {
15
17
  parseMarkdownString,
16
18
  posixPath,
17
19
  Globby,
20
+ normalizeFrontMatterTags,
18
21
  } from '@docusaurus/utils';
19
22
  import {LoadContext} from '@docusaurus/types';
20
23
 
@@ -22,17 +25,21 @@ import {getFileLastUpdate} from './lastUpdate';
22
25
  import {
23
26
  DocFile,
24
27
  DocMetadataBase,
28
+ DocMetadata,
29
+ DocNavLink,
25
30
  LastUpdateData,
26
31
  MetadataOptions,
27
32
  PluginOptions,
28
33
  VersionMetadata,
34
+ LoadedVersion,
29
35
  } from './types';
30
36
  import getSlug from './slug';
31
37
  import {CURRENT_VERSION_NAME} from './constants';
32
38
  import {getDocsDirPaths} from './versions';
33
39
  import {stripPathNumberPrefixes} from './numberPrefix';
34
40
  import {validateDocFrontMatter} from './docFrontMatter';
35
- import chalk from 'chalk';
41
+ import type {Sidebars} from './sidebars/types';
42
+ import {createSidebarsUtils} from './sidebars/utils';
36
43
 
37
44
  type LastUpdateOptions = Pick<
38
45
  PluginOptions,
@@ -130,9 +137,8 @@ function doProcessDocMetadata({
130
137
  custom_edit_url: customEditURL,
131
138
 
132
139
  // Strip number prefixes by default (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc) by default,
133
- // but allow to disable this behavior with frontmatterr
134
- // eslint-disable-next-line camelcase
135
- parse_number_prefixes = true,
140
+ // but allow to disable this behavior with frontmatter
141
+ parse_number_prefixes: parseNumberPrefixes = true,
136
142
  } = frontMatter;
137
143
 
138
144
  // ex: api/plugins/myDoc -> myDoc
@@ -146,8 +152,7 @@ function doProcessDocMetadata({
146
152
  // ex: myDoc -> .
147
153
  const sourceDirName = path.dirname(source);
148
154
 
149
- // eslint-disable-next-line camelcase
150
- const {filename: unprefixedFileName, numberPrefix} = parse_number_prefixes
155
+ const {filename: unprefixedFileName, numberPrefix} = parseNumberPrefixes
151
156
  ? options.numberPrefixParser(sourceFileNameWithoutExtension)
152
157
  : {filename: sourceFileNameWithoutExtension, numberPrefix: undefined};
153
158
 
@@ -175,8 +180,7 @@ function doProcessDocMetadata({
175
180
  return undefined;
176
181
  }
177
182
  // Eventually remove the number prefixes from intermediate directories
178
- // eslint-disable-next-line camelcase
179
- return parse_number_prefixes
183
+ return parseNumberPrefixes
180
184
  ? stripPathNumberPrefixes(sourceDirName, options.numberPrefixParser)
181
185
  : sourceDirName;
182
186
  }
@@ -203,7 +207,7 @@ function doProcessDocMetadata({
203
207
  baseID,
204
208
  dirName: sourceDirName,
205
209
  frontmatterSlug: frontMatter.slug,
206
- stripDirNumberPrefixes: parse_number_prefixes,
210
+ stripDirNumberPrefixes: parseNumberPrefixes,
207
211
  numberPrefixParser: options.numberPrefixParser,
208
212
  });
209
213
 
@@ -255,6 +259,7 @@ function doProcessDocMetadata({
255
259
  slug: docSlug,
256
260
  permalink,
257
261
  editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
262
+ tags: normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags),
258
263
  version: versionMetadata.versionName,
259
264
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
260
265
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
@@ -285,3 +290,77 @@ export function processDocMetadata(args: {
285
290
  throw e;
286
291
  }
287
292
  }
293
+
294
+ export function handleNavigation(
295
+ docsBase: DocMetadataBase[],
296
+ sidebars: Sidebars,
297
+ sidebarFilePath: string,
298
+ ): Pick<LoadedVersion, 'mainDocId' | 'docs'> {
299
+ const docsBaseById = keyBy(docsBase, (doc) => doc.id);
300
+ const {checkSidebarsDocIds, getDocNavigation, getFirstDocIdOfFirstSidebar} =
301
+ createSidebarsUtils(sidebars);
302
+
303
+ const validDocIds = Object.keys(docsBaseById);
304
+ checkSidebarsDocIds(validDocIds, sidebarFilePath);
305
+
306
+ // Add sidebar/next/previous to the docs
307
+ function addNavData(doc: DocMetadataBase): DocMetadata {
308
+ const {sidebarName, previousId, nextId} = getDocNavigation(doc.id);
309
+ const toDocNavLink = (
310
+ docId: string | null | undefined,
311
+ type: 'prev' | 'next',
312
+ ): DocNavLink | undefined => {
313
+ if (!docId) {
314
+ return undefined;
315
+ }
316
+ if (!docsBaseById[docId]) {
317
+ // This could only happen if user provided the ID through front matter
318
+ throw new Error(
319
+ `Error when loading ${doc.id} in ${doc.sourceDirName}: the pagination_${type} front matter points to a non-existent ID ${docId}.`,
320
+ );
321
+ }
322
+ const {
323
+ title,
324
+ permalink,
325
+ frontMatter: {
326
+ pagination_label: paginationLabel,
327
+ sidebar_label: sidebarLabel,
328
+ },
329
+ } = docsBaseById[docId];
330
+ return {title: paginationLabel ?? sidebarLabel ?? title, permalink};
331
+ };
332
+ const {
333
+ frontMatter: {
334
+ pagination_next: paginationNext = nextId,
335
+ pagination_prev: paginationPrev = previousId,
336
+ },
337
+ } = doc;
338
+ const previous = toDocNavLink(paginationPrev, 'prev');
339
+ const next = toDocNavLink(paginationNext, 'next');
340
+ return {...doc, sidebar: sidebarName, previous, next};
341
+ }
342
+ const docs = docsBase.map(addNavData);
343
+ // sort to ensure consistent output for tests
344
+ docs.sort((a, b) => a.id.localeCompare(b.id));
345
+
346
+ /**
347
+ * The "main doc" is the "version entry point"
348
+ * We browse this doc by clicking on a version:
349
+ * - the "home" doc (at '/docs/')
350
+ * - the first doc of the first sidebar
351
+ * - a random doc (if no docs are in any sidebar... edge case)
352
+ */
353
+ function getMainDoc(): DocMetadata {
354
+ const versionHomeDoc = docs.find((doc) => doc.slug === '/');
355
+ const firstDocIdOfFirstSidebar = getFirstDocIdOfFirstSidebar();
356
+ if (versionHomeDoc) {
357
+ return versionHomeDoc;
358
+ } else if (firstDocIdOfFirstSidebar) {
359
+ return docs.find((doc) => doc.id === firstDocIdOfFirstSidebar)!;
360
+ } else {
361
+ return docs[0];
362
+ }
363
+ }
364
+
365
+ return {mainDocId: getMainDoc().unversionedId, docs};
366
+ }