@mintlify/common 1.0.1108 → 1.0.1109

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.
@@ -154,10 +154,10 @@ function divisionValue(division, key) {
154
154
  const value = key === 'versions' ? division.version : division.language;
155
155
  return typeof value === 'string' ? value : undefined;
156
156
  }
157
- function resolveStubTarget(division, key, ctx) {
157
+ function resolveStubTarget(division, key, ctx, usePrecomputedTarget) {
158
158
  const targets = key === 'versions' ? ctx.versionTargets : ctx.languageTargets;
159
159
  const value = divisionValue(division, key);
160
- const resolved = targets === null || targets === void 0 ? void 0 : targets.get(value);
160
+ const resolved = usePrecomputedTarget ? targets === null || targets === void 0 ? void 0 : targets.get(value) : undefined;
161
161
  const fallback = pickStubTarget(division, ctx, DIVISION_TYPE_BY_KEY[key]);
162
162
  // the jump-map walk records targets without access checks, so a precomputed
163
163
  // entry only supplies the switch destination; hidden/groups still come from
@@ -172,10 +172,10 @@ function resolveStubTarget(division, key, ctx) {
172
172
  }
173
173
  return fallback;
174
174
  }
175
- function stubDivision(division, key, ctx) {
175
+ function stubDivision(division, key, ctx, usePrecomputedTarget) {
176
176
  if (typeof division.href === 'string')
177
177
  return division;
178
- const target = resolveStubTarget(division, key, ctx);
178
+ const target = resolveStubTarget(division, key, ctx, usePrecomputedTarget);
179
179
  // a division with no page candidates carries no page payload worth stripping,
180
180
  // so keep it unchanged rather than inventing a switch target
181
181
  if (!target)
@@ -328,6 +328,9 @@ function scopeDivisionArray(entries, key, ctx) {
328
328
  }
329
329
  const currentValue = key === 'versions' ? ctx.currentVersion : ctx.currentLanguage;
330
330
  const containsPath = entries.map((entry) => isNavNode(entry) && divisionContainsPath(entry, ctx.currentPath));
331
+ // Precomputed targets belong to the version/language block that owns the
332
+ // current path. Reusing them in an off-path sibling can cross dropdowns.
333
+ const usePrecomputedTarget = containsPath.some(Boolean);
331
334
  let activeIndex = -1;
332
335
  if (currentValue) {
333
336
  activeIndex = entries.findIndex((entry, index) => isNavNode(entry) && divisionValue(entry, key) === currentValue && containsPath[index]);
@@ -354,7 +357,7 @@ function scopeDivisionArray(entries, key, ctx) {
354
357
  // a stub would collapse the sidebar to its single switch-target page
355
358
  if (containsPath[index])
356
359
  return scopeNode(entry, ctx);
357
- return stubDivision(entry, key, ctx);
360
+ return stubDivision(entry, key, ctx, usePrecomputedTarget);
358
361
  });
359
362
  }
360
363
  function collectProductVersionMetadata(node, out, seen) {
@@ -167,6 +167,38 @@ const dropdownNav = {
167
167
  },
168
168
  ],
169
169
  };
170
+ const parallelVersionedDropdownNav = {
171
+ dropdowns: [
172
+ {
173
+ dropdown: 'Primary API',
174
+ versions: [
175
+ {
176
+ version: 'v2',
177
+ pages: [{ title: 'Overview', href: '/api/primary/v2/overview' }],
178
+ },
179
+ {
180
+ version: 'v1',
181
+ default: true,
182
+ pages: [{ title: 'Overview', href: '/api/primary/v1/overview' }],
183
+ },
184
+ ],
185
+ },
186
+ {
187
+ dropdown: 'Secondary API',
188
+ versions: [
189
+ {
190
+ version: 'v2',
191
+ pages: [{ title: 'Overview', href: '/api/secondary/v2/overview' }],
192
+ },
193
+ {
194
+ version: 'v1',
195
+ default: true,
196
+ pages: [{ title: 'Overview', href: '/api/secondary/v1/overview' }],
197
+ },
198
+ ],
199
+ },
200
+ ],
201
+ };
170
202
  // groups: [] denies every viewer (checkNavAccess), unlike an absent groups key
171
203
  const denyAllGroupsTabNav = {
172
204
  tabs: [
@@ -639,6 +671,18 @@ describe('off-path tab and anchor stubbing', () => {
639
671
  expect(scopedNav.dropdowns[1]).toEqual(dropdownNav.dropdowns[1]);
640
672
  expect(scopedNav.dropdowns[2]).toEqual(dropdownNav.dropdowns[2]);
641
673
  });
674
+ it('keeps version targets within their dropdown when version labels are reused', () => {
675
+ var _a;
676
+ const currentPath = '/api/secondary/v1/overview';
677
+ const scoped = getScopedNavForPath({
678
+ decoratedNav: parallelVersionedDropdownNav,
679
+ currentPath,
680
+ });
681
+ const full = filterWith(parallelVersionedDropdownNav, currentPath, scoped.currentVersion, scoped.currentLanguage);
682
+ const rescoped = filterWith(scoped.scopedNav, currentPath, scoped.currentVersion, scoped.currentLanguage);
683
+ expect((_a = rescoped.dropdowns.find(({ name }) => name === 'Primary API')) === null || _a === void 0 ? void 0 : _a.href).toBe('/api/primary/v1/overview');
684
+ expect(chromeSummary(rescoped)).toEqual(chromeSummary(full));
685
+ });
642
686
  it('keeps hidden/gated sibling versions invisible even with precomputed jump targets', () => {
643
687
  assertChromeInvariantForEveryPath(hiddenVersionNav);
644
688
  assertChromeInvariantForEveryPath(hiddenVersionNav, false, new Set(['staff']));