@mintlify/common 1.0.1076 → 1.0.1078
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.
|
@@ -7,7 +7,7 @@ import { isEqualIgnoringLeadingSlash } from '../paths/isEqualIgnoringLeadingSlas
|
|
|
7
7
|
import { checkNavAccess } from './checkNavAccess.js';
|
|
8
8
|
import { getFirstPageFromNavigation } from './getFirstPageFromNavigation.js';
|
|
9
9
|
import { isPage } from './isPage.js';
|
|
10
|
-
import { updateFirstHrefInDivision } from './updateFirstHrefInDivision.js';
|
|
10
|
+
import { pathsDifferByOneSegment, updateFirstHrefInDivision, } from './updateFirstHrefInDivision.js';
|
|
11
11
|
const DIVISION_NAME_MAP = {
|
|
12
12
|
tabs: 'tab',
|
|
13
13
|
anchors: 'anchor',
|
|
@@ -155,6 +155,7 @@ export const filterDivisions = ({ currentPath, currentVersion, currentLanguage,
|
|
|
155
155
|
item,
|
|
156
156
|
isActive,
|
|
157
157
|
cache,
|
|
158
|
+
currentPath,
|
|
158
159
|
currentVersion,
|
|
159
160
|
currentLanguage,
|
|
160
161
|
userGroups,
|
|
@@ -260,8 +261,8 @@ function upsertGlobalDivisions(navigationDivisions, globalConfig) {
|
|
|
260
261
|
});
|
|
261
262
|
}
|
|
262
263
|
function buildDivisionItem(param) {
|
|
263
|
-
var _a;
|
|
264
|
-
const { item, isActive, cache, currentVersion, currentLanguage, userGroups, divisionKey, menuDivision, isPreview = false, parentDivisionNames = [], } = param;
|
|
264
|
+
var _a, _b;
|
|
265
|
+
const { item, isActive, cache, currentPath, currentVersion, currentLanguage, userGroups, divisionKey, menuDivision, isPreview = false, parentDivisionNames = [], } = param;
|
|
265
266
|
const { dropdownCache } = cache;
|
|
266
267
|
let href = '';
|
|
267
268
|
// TODO: support this for other divisions (versions, languages, etc.)
|
|
@@ -282,11 +283,17 @@ function buildDivisionItem(param) {
|
|
|
282
283
|
// if href is absolute url, use it, otherwise use the href from the first page
|
|
283
284
|
if (!href) {
|
|
284
285
|
const isUserDefinedHref = 'href' in item && isAbsoluteUrl(item.href);
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
286
|
+
if (!isUserDefinedHref && divisionKey === 'dropdowns' && !isActive && currentPath) {
|
|
287
|
+
href =
|
|
288
|
+
(_b = findCorrespondingDropdownHref(item, currentPath, userGroups !== null && userGroups !== void 0 ? userGroups : new Set(), isPreview)) !== null && _b !== void 0 ? _b : '';
|
|
289
|
+
}
|
|
290
|
+
if (!href) {
|
|
291
|
+
href = isUserDefinedHref ? item.href : (page === null || page === void 0 ? void 0 : page.href) || '/';
|
|
292
|
+
// when users switch languages, we should stay on the same page
|
|
293
|
+
// instead of switching to the first page in the new language
|
|
294
|
+
if (!isUserDefinedHref && divisionKey === 'languages') {
|
|
295
|
+
href = '';
|
|
296
|
+
}
|
|
290
297
|
}
|
|
291
298
|
}
|
|
292
299
|
const baseResult = Object.assign(Object.assign({ name: findDivisionName(item) }, divisionItem), { href: href, isActive, isGlobal: false });
|
|
@@ -306,6 +313,7 @@ function buildDivisionItem(param) {
|
|
|
306
313
|
item: menuItem,
|
|
307
314
|
isActive: false, // menu items are not active by default
|
|
308
315
|
cache,
|
|
316
|
+
currentPath,
|
|
309
317
|
currentVersion,
|
|
310
318
|
currentLanguage,
|
|
311
319
|
userGroups,
|
|
@@ -322,6 +330,52 @@ function buildDivisionItem(param) {
|
|
|
322
330
|
}
|
|
323
331
|
return baseResult;
|
|
324
332
|
}
|
|
333
|
+
function findCorrespondingDropdownHref(item, currentPath, userGroups, isPreview) {
|
|
334
|
+
let exactMatch;
|
|
335
|
+
let segmentMatch;
|
|
336
|
+
function walk(entry) {
|
|
337
|
+
if (exactMatch !== undefined || typeof entry !== 'object')
|
|
338
|
+
return;
|
|
339
|
+
if (isPage(entry)) {
|
|
340
|
+
if (!checkNavAccess(entry, userGroups, isPreview))
|
|
341
|
+
return;
|
|
342
|
+
if (isEqualIgnoringLeadingSlash(entry.href, currentPath)) {
|
|
343
|
+
exactMatch = entry.href;
|
|
344
|
+
}
|
|
345
|
+
else if (segmentMatch === undefined &&
|
|
346
|
+
pathsDifferByOneSegment(entry.href, currentPath, 'version')) {
|
|
347
|
+
segmentMatch = entry.href;
|
|
348
|
+
}
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if ('hidden' in entry && entry.hidden)
|
|
352
|
+
return;
|
|
353
|
+
if ('root' in entry && typeof entry.root === 'object') {
|
|
354
|
+
walk(entry.root);
|
|
355
|
+
}
|
|
356
|
+
if ('pages' in entry && Array.isArray(entry.pages)) {
|
|
357
|
+
for (const page of entry.pages) {
|
|
358
|
+
if (typeof page === 'object')
|
|
359
|
+
walk(page);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if ('groups' in entry && Array.isArray(entry.groups)) {
|
|
363
|
+
for (const group of entry.groups) {
|
|
364
|
+
walk(group);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
for (const key of divisions) {
|
|
368
|
+
const subDivisions = readObjectArrayProperty(entry, key);
|
|
369
|
+
if (!subDivisions)
|
|
370
|
+
continue;
|
|
371
|
+
for (const subDivision of subDivisions) {
|
|
372
|
+
walk(subDivision);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
walk(item);
|
|
377
|
+
return exactMatch !== null && exactMatch !== void 0 ? exactMatch : segmentMatch;
|
|
378
|
+
}
|
|
325
379
|
function getFirstPageFromCurrentDivisions(item, currentVersion, currentLanguage, userGroups, isPreview = false) {
|
|
326
380
|
var _a, _b;
|
|
327
381
|
if ('versions' in item && currentVersion) {
|
|
@@ -629,6 +683,7 @@ function findMostRelevantDivisions(currentPath, decoratedNav, currentVersion, cu
|
|
|
629
683
|
item,
|
|
630
684
|
isActive,
|
|
631
685
|
cache,
|
|
686
|
+
currentPath,
|
|
632
687
|
currentVersion,
|
|
633
688
|
currentLanguage,
|
|
634
689
|
userGroups,
|
|
@@ -668,3 +668,124 @@ describe('filterDivisions with partial auth', () => {
|
|
|
668
668
|
});
|
|
669
669
|
});
|
|
670
670
|
});
|
|
671
|
+
describe('filterDivisions dropdown corresponding pages', () => {
|
|
672
|
+
const defaultArgs = {
|
|
673
|
+
decoratedNav: { groups: [] },
|
|
674
|
+
currentPath: '',
|
|
675
|
+
userGroups: new Set(),
|
|
676
|
+
currentVersion: '',
|
|
677
|
+
currentLanguage: undefined,
|
|
678
|
+
shouldUseDivisionMatch: true,
|
|
679
|
+
cache: {
|
|
680
|
+
dropdownCache: new Map(),
|
|
681
|
+
},
|
|
682
|
+
};
|
|
683
|
+
const versionedDropdownNav = {
|
|
684
|
+
dropdowns: [
|
|
685
|
+
{
|
|
686
|
+
dropdown: 'Version 0.22',
|
|
687
|
+
groups: [
|
|
688
|
+
{
|
|
689
|
+
group: 'Get Started',
|
|
690
|
+
pages: [
|
|
691
|
+
{ title: 'Overview', href: '/vega/0.22/overview' },
|
|
692
|
+
{ title: 'Install', href: '/vega/0.22/install' },
|
|
693
|
+
{ title: 'New Feature', href: '/vega/0.22/new-feature' },
|
|
694
|
+
],
|
|
695
|
+
},
|
|
696
|
+
],
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
dropdown: 'Version 0.21',
|
|
700
|
+
groups: [
|
|
701
|
+
{
|
|
702
|
+
group: 'Get Started',
|
|
703
|
+
pages: [
|
|
704
|
+
{ title: 'Overview', href: '/vega/0.21/overview' },
|
|
705
|
+
{ title: 'Install', href: '/vega/0.21/install' },
|
|
706
|
+
],
|
|
707
|
+
},
|
|
708
|
+
],
|
|
709
|
+
},
|
|
710
|
+
],
|
|
711
|
+
};
|
|
712
|
+
it('points inactive dropdowns at the corresponding page when one exists', () => {
|
|
713
|
+
var _a;
|
|
714
|
+
const result = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav: versionedDropdownNav, currentPath: '/vega/0.21/install' }));
|
|
715
|
+
expect((_a = result.dropdowns.find((d) => d.name === 'Version 0.22')) === null || _a === void 0 ? void 0 : _a.href).toBe('/vega/0.22/install');
|
|
716
|
+
});
|
|
717
|
+
it('keeps the first page href for the active dropdown', () => {
|
|
718
|
+
const result = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav: versionedDropdownNav, currentPath: '/vega/0.21/install' }));
|
|
719
|
+
const active = result.dropdowns.find(isActiveDivision);
|
|
720
|
+
expect(active === null || active === void 0 ? void 0 : active.name).toBe('Version 0.21');
|
|
721
|
+
expect(active === null || active === void 0 ? void 0 : active.href).toBe('/vega/0.21/overview');
|
|
722
|
+
});
|
|
723
|
+
it('falls back to the first page when no corresponding page exists', () => {
|
|
724
|
+
var _a;
|
|
725
|
+
const result = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav: versionedDropdownNav, currentPath: '/vega/0.22/new-feature' }));
|
|
726
|
+
expect((_a = result.dropdowns.find((d) => d.name === 'Version 0.21')) === null || _a === void 0 ? void 0 : _a.href).toBe('/vega/0.21/overview');
|
|
727
|
+
});
|
|
728
|
+
it('prefers a shared page at the same href over a segment match', () => {
|
|
729
|
+
var _a;
|
|
730
|
+
const result = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav: {
|
|
731
|
+
dropdowns: [
|
|
732
|
+
{
|
|
733
|
+
dropdown: 'Guides',
|
|
734
|
+
pages: [
|
|
735
|
+
{ title: 'Intro', href: '/guides/intro' },
|
|
736
|
+
{ title: 'Changelog', href: '/changelog/latest' },
|
|
737
|
+
],
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
dropdown: 'Reference',
|
|
741
|
+
pages: [
|
|
742
|
+
{ title: 'Intro', href: '/reference/intro' },
|
|
743
|
+
{ title: 'Changelog', href: '/changelog/latest' },
|
|
744
|
+
],
|
|
745
|
+
},
|
|
746
|
+
],
|
|
747
|
+
}, currentPath: '/changelog/latest' }));
|
|
748
|
+
expect((_a = result.dropdowns.find((d) => d.name === 'Reference')) === null || _a === void 0 ? void 0 : _a.href).toBe('/changelog/latest');
|
|
749
|
+
});
|
|
750
|
+
it('skips corresponding pages the viewer cannot access', () => {
|
|
751
|
+
var _a, _b;
|
|
752
|
+
const decoratedNav = {
|
|
753
|
+
dropdowns: [
|
|
754
|
+
{
|
|
755
|
+
dropdown: 'Version 0.22',
|
|
756
|
+
pages: [
|
|
757
|
+
{ title: 'Overview', href: '/vega/0.22/overview' },
|
|
758
|
+
{ title: 'Install', href: '/vega/0.22/install', groups: ['admin'] },
|
|
759
|
+
],
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
dropdown: 'Version 0.21',
|
|
763
|
+
pages: [
|
|
764
|
+
{ title: 'Overview', href: '/vega/0.21/overview' },
|
|
765
|
+
{ title: 'Install', href: '/vega/0.21/install' },
|
|
766
|
+
],
|
|
767
|
+
},
|
|
768
|
+
],
|
|
769
|
+
};
|
|
770
|
+
const anonymous = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav, currentPath: '/vega/0.21/install' }));
|
|
771
|
+
expect((_a = anonymous.dropdowns.find((d) => d.name === 'Version 0.22')) === null || _a === void 0 ? void 0 : _a.href).toBe('/vega/0.22/overview');
|
|
772
|
+
const admin = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav, currentPath: '/vega/0.21/install', userGroups: new Set(['admin']) }));
|
|
773
|
+
expect((_b = admin.dropdowns.find((d) => d.name === 'Version 0.22')) === null || _b === void 0 ? void 0 : _b.href).toBe('/vega/0.22/install');
|
|
774
|
+
});
|
|
775
|
+
it('matches corresponding pages for dropdowns nested inside tabs', () => {
|
|
776
|
+
var _a;
|
|
777
|
+
const result = filterDivisions(Object.assign(Object.assign({}, defaultArgs), { decoratedNav: {
|
|
778
|
+
tabs: [
|
|
779
|
+
{
|
|
780
|
+
tab: 'Get Started',
|
|
781
|
+
dropdowns: versionedDropdownNav.dropdowns,
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
tab: 'Support',
|
|
785
|
+
pages: [{ title: 'Help', href: '/support/help' }],
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
}, currentPath: '/vega/0.21/install' }));
|
|
789
|
+
expect((_a = result.dropdowns.find((d) => d.name === 'Version 0.22')) === null || _a === void 0 ? void 0 : _a.href).toBe('/vega/0.22/install');
|
|
790
|
+
});
|
|
791
|
+
});
|