@fern-api/fdr-sdk 1.2.39-b5d93657fe → 1.2.39-bf608e8e3c

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 (36) hide show
  1. package/dist/js/client/FdrClient.js +1 -0
  2. package/dist/js/client/FdrClient.js.map +1 -1
  3. package/dist/js/client/FdrClient.mjs +1 -0
  4. package/dist/js/client/FdrClient.mjs.map +1 -1
  5. package/dist/js/index.js +1 -0
  6. package/dist/js/index.js.map +1 -1
  7. package/dist/js/index.mjs +1 -0
  8. package/dist/js/index.mjs.map +1 -1
  9. package/dist/js/navigation/ledger-root-builder.js +234 -57
  10. package/dist/js/navigation/ledger-root-builder.js.map +1 -1
  11. package/dist/js/navigation/ledger-root-builder.mjs +234 -57
  12. package/dist/js/navigation/ledger-root-builder.mjs.map +1 -1
  13. package/dist/js/orpc-client.js +1 -0
  14. package/dist/js/orpc-client.js.map +1 -1
  15. package/dist/js/orpc-client.mjs +1 -0
  16. package/dist/js/orpc-client.mjs.map +1 -1
  17. package/dist/tsconfig.tsbuildinfo +1 -1
  18. package/dist/types/navigation/__test__/ledger-root-builder.apiReferenceChildren.test.d.ts +2 -0
  19. package/dist/types/navigation/__test__/ledger-root-builder.apiReferenceChildren.test.d.ts.map +1 -0
  20. package/dist/types/navigation/__test__/ledger-root-builder.landingPage.test.d.ts +2 -0
  21. package/dist/types/navigation/__test__/ledger-root-builder.landingPage.test.d.ts.map +1 -0
  22. package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.test.d.ts +2 -0
  23. package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.test.d.ts.map +1 -0
  24. package/dist/types/navigation/__test__/ledger-root-builder.rootSlug.test.d.ts +2 -0
  25. package/dist/types/navigation/__test__/ledger-root-builder.rootSlug.test.d.ts.map +1 -0
  26. package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts +2 -0
  27. package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts.map +1 -0
  28. package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts +2 -0
  29. package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts.map +1 -0
  30. package/dist/types/navigation/ledger-root-builder.d.ts +12 -0
  31. package/dist/types/navigation/ledger-root-builder.d.ts.map +1 -1
  32. package/dist/types/orpc-client/docs-ledger/contract.d.ts +50 -0
  33. package/dist/types/orpc-client/docs-ledger/contract.d.ts.map +1 -1
  34. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts +12 -0
  35. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts.map +1 -1
  36. package/package.json +3 -3
@@ -1082,6 +1082,63 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1082
1082
  }
1083
1083
  return void 0;
1084
1084
  }
1085
+ function apiLeafPositionKey(node) {
1086
+ switch (node.type) {
1087
+ case "endpoint":
1088
+ return `endpoint:${node.endpointId}`;
1089
+ case "webhook":
1090
+ return `webhook:${node.webhookId}`;
1091
+ case "webSocket":
1092
+ return `webSocket:${node.webSocketId}`;
1093
+ case "grpc":
1094
+ return `grpc:${node.grpcId}`;
1095
+ case "graphql":
1096
+ return `graphql:${node.graphqlOperationId}`;
1097
+ }
1098
+ }
1099
+ function apiChildPositionKey(node) {
1100
+ switch (node.type) {
1101
+ case "endpoint":
1102
+ case "webhook":
1103
+ case "webSocket":
1104
+ case "grpc":
1105
+ case "graphql":
1106
+ return apiLeafPositionKey(node);
1107
+ default:
1108
+ return void 0;
1109
+ }
1110
+ }
1111
+ function positionedApiLeafChildren(ctx, nav, apiDefinitionId) {
1112
+ const rawLeafNodes = [];
1113
+ const leafPositions = /* @__PURE__ */ new Map();
1114
+ const nonApiLeafNodes = [];
1115
+ for (let i = 0; i < nav.length; i++) {
1116
+ const route = nav[i];
1117
+ const pos = route.displaySortOrder ?? i;
1118
+ const apiLeaf = apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId);
1119
+ if (apiLeaf != null) {
1120
+ rawLeafNodes.push(apiLeaf);
1121
+ const key = apiLeafPositionKey(apiLeaf);
1122
+ leafPositions.set(key, Math.min(leafPositions.get(key) ?? pos, pos));
1123
+ continue;
1124
+ }
1125
+ const node = artifactToNode(ctx, route);
1126
+ if (node?.type === "page" || node?.type === "link") {
1127
+ nonApiLeafNodes.push({ node, pos });
1128
+ }
1129
+ }
1130
+ const apiLeafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
1131
+ const positionedApiLeafNodes = apiLeafNodes.map((node, index) => {
1132
+ if (node.type === "endpointPair") {
1133
+ const streamPos = leafPositions.get(apiLeafPositionKey(node.stream)) ?? index;
1134
+ const nonStreamPos = leafPositions.get(apiLeafPositionKey(node.nonStream)) ?? index;
1135
+ return { node, pos: Math.min(streamPos, nonStreamPos) };
1136
+ }
1137
+ const key = apiChildPositionKey(node);
1138
+ return { node, pos: key != null ? leafPositions.get(key) ?? index : index };
1139
+ });
1140
+ return [...positionedApiLeafNodes, ...nonApiLeafNodes];
1141
+ }
1085
1142
  function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefinitionId2) {
1086
1143
  const ctx = createBuildContext(basePath);
1087
1144
  return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2)).filter((node) => node != null);
@@ -1194,7 +1251,7 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1194
1251
  collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1195
1252
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1196
1253
  noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1197
- collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
1254
+ collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1198
1255
  collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1199
1256
  availability: metaStr(seg.metadata, "availability"),
1200
1257
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
@@ -1219,8 +1276,7 @@ function directChildApiPackages(parentSection, scopeSegs) {
1219
1276
  }
1220
1277
  function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix) {
1221
1278
  const { seg, nav } = scoped;
1222
- const rawLeafNodes = nav.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId)).filter((node) => node != null);
1223
- const leafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
1279
+ const leafNodes = positionedApiLeafChildren(ctx, nav, apiDefinitionId);
1224
1280
  const childPackages = directChildApiPackages(seg.section, scopeSegs);
1225
1281
  const packageNodes = childPackages.map((child) => ({
1226
1282
  node: apiPackageChildNode(
@@ -1234,18 +1290,10 @@ function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix)
1234
1290
  }));
1235
1291
  const hasChildIndex = packageNodes.some((p) => p.childIndex != null);
1236
1292
  if (!hasChildIndex) {
1237
- return [...leafNodes, ...packageNodes.map((p) => p.node)];
1238
- }
1239
- const leafPositions = [];
1240
- for (const route of nav) {
1241
- if (route.displaySortOrder != null) {
1242
- leafPositions.push(route.displaySortOrder);
1243
- }
1293
+ return [...leafNodes, ...packageNodes.map((p) => ({ node: p.node, pos: Number.MAX_SAFE_INTEGER }))].sort((a, b) => a.pos - b.pos).map((p) => p.node);
1244
1294
  }
1245
1295
  const positioned = [];
1246
- for (let i = 0; i < leafNodes.length; i++) {
1247
- positioned.push({ node: leafNodes[i], pos: leafPositions[i] ?? i });
1248
- }
1296
+ positioned.push(...leafNodes);
1249
1297
  for (const p of packageNodes) {
1250
1298
  positioned.push({ node: p.node, pos: p.childIndex ?? Number.MAX_SAFE_INTEGER });
1251
1299
  }
@@ -1430,7 +1478,7 @@ function changelogNode(ctx, scoped, scopePrefix) {
1430
1478
  pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
1431
1479
  noindex: metaBool(r.metadata, "noindex"),
1432
1480
  date: dateStr ?? "",
1433
- tags: void 0
1481
+ tags: metaStrArr(r.metadata, "tags")
1434
1482
  };
1435
1483
  let months = byYear.get(year);
1436
1484
  if (months == null) {
@@ -1537,17 +1585,55 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
1537
1585
  return { node, childIndex };
1538
1586
  });
1539
1587
  }
1588
+ function computeSiblingSortBoundaries(ordered) {
1589
+ const result = /* @__PURE__ */ new Map();
1590
+ const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1591
+ const rootSections = [];
1592
+ for (const s of ordered) {
1593
+ const type = metaStr(s.seg.metadata, "type");
1594
+ const sec = s.seg.section;
1595
+ if (type !== "section" || sec === "") {
1596
+ continue;
1597
+ }
1598
+ const parent = parentSectionPath(sec);
1599
+ const isRootLevel = parent === "" || !sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "";
1600
+ if (isRootLevel) {
1601
+ rootSections.push(s);
1602
+ }
1603
+ }
1604
+ const byPath = /* @__PURE__ */ new Map();
1605
+ for (const s of rootSections) {
1606
+ const group = byPath.get(s.seg.section) ?? [];
1607
+ group.push(s);
1608
+ byPath.set(s.seg.section, group);
1609
+ }
1610
+ for (const [, siblings] of byPath) {
1611
+ if (siblings.length <= 1) {
1612
+ continue;
1613
+ }
1614
+ for (let i = 0; i < siblings.length; i++) {
1615
+ const lo = siblings[i].seg.sortOrder;
1616
+ const hi = i + 1 < siblings.length ? siblings[i + 1].seg.sortOrder : Number.MAX_SAFE_INTEGER;
1617
+ result.set(siblings[i], { lo, hi });
1618
+ }
1619
+ }
1620
+ return result;
1621
+ }
1540
1622
  function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1541
1623
  const ordered = [...scopeSegs].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1542
1624
  const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1543
1625
  const annotated = [];
1544
1626
  const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" && s.seg.section === "");
1627
+ const siblingBoundaries = computeSiblingSortBoundaries(ordered);
1545
1628
  for (const s of ordered) {
1546
1629
  const type = metaStr(s.seg.metadata, "type");
1547
1630
  const sec = s.seg.section;
1548
1631
  if (hasOwningApiReference(s, scopeSegs)) {
1549
1632
  continue;
1550
1633
  }
1634
+ if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
1635
+ continue;
1636
+ }
1551
1637
  if (type === "tabRoot" || sec === "" && type !== "section") {
1552
1638
  for (const r of s.nav) {
1553
1639
  const node = artifactToNode(ctx, r);
@@ -1575,14 +1661,21 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
1575
1661
  } else if (type === "changelog") {
1576
1662
  node = changelogNode(ctx, s, changelogScopePrefix ?? scopePrefix);
1577
1663
  } else {
1664
+ const bounds = siblingBoundaries.get(s);
1665
+ const ownedSegs = bounds != null ? scopeSegs.filter((seg) => seg.seg.sortOrder >= bounds.lo && seg.seg.sortOrder < bounds.hi) : scopeSegs;
1578
1666
  node = sectionNode(
1579
1667
  ctx,
1580
1668
  s,
1581
- buildSectionTree(ctx, scopeSegs, sec, scopePrefix, changelogScopePrefix),
1669
+ buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix),
1582
1670
  scopePrefix
1583
1671
  );
1584
1672
  }
1585
- annotated.push({ node, pos: metaNum(s.seg.metadata, "childIndex"), isLeaf: false });
1673
+ const isSharedSection = siblingBoundaries.size > 0 && scopePrefix !== "" && sec !== "" && !sec.startsWith(scopePrefix);
1674
+ annotated.push({
1675
+ node,
1676
+ pos: isSharedSection ? void 0 : metaNum(s.seg.metadata, "childIndex"),
1677
+ isLeaf: false
1678
+ });
1586
1679
  }
1587
1680
  }
1588
1681
  const hasLeafPos = annotated.some((a) => a.isLeaf && a.pos != null);
@@ -1634,13 +1727,13 @@ function buildSidebarRoot(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1634
1727
  };
1635
1728
  }
1636
1729
  function buildFullRootFromSegments(options) {
1637
- const { basePath, title, segments, navBySegment } = options;
1730
+ const { basePath, rootSlug: sourceRootSlug, title, segments, navBySegment, skipSharedSectionMerge } = options;
1638
1731
  const ctx = createBuildContext(basePath);
1639
1732
  const scoped = segments.filter((seg) => {
1640
1733
  const t = metaStr(seg.metadata, "type");
1641
1734
  return t !== "files" && t !== "redirects";
1642
1735
  }).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
1643
- const rootSlug = asSlug(basePath);
1736
+ const rootSlug = asSlug(sourceRootSlug ?? basePath);
1644
1737
  const scopesByKey = /* @__PURE__ */ new Map();
1645
1738
  for (const s of scoped) {
1646
1739
  const key = scopeKey(s.seg);
@@ -1653,9 +1746,9 @@ function buildFullRootFromSegments(options) {
1653
1746
  const tabs = uniqueDetails(scoped, "tab");
1654
1747
  let child;
1655
1748
  if (products.length > 0) {
1656
- child = buildProductGroup(ctx, products, scoped, rootSlug);
1749
+ child = buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge);
1657
1750
  } else if (versions.length > 0) {
1658
- child = buildVersioned(ctx, versions, scoped, rootSlug, void 0);
1751
+ child = buildVersioned(ctx, versions, scoped, rootSlug, void 0, skipSharedSectionMerge);
1659
1752
  } else {
1660
1753
  child = buildUnversioned(ctx, scoped, rootSlug, tabs.length > 0);
1661
1754
  }
@@ -1666,6 +1759,24 @@ function buildFullRootFromSegments(options) {
1666
1759
  } else if (child.type === "versioned") {
1667
1760
  const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
1668
1761
  rootPointsTo = defaultVersion?.pointsTo;
1762
+ } else if (child.type === "unversioned") {
1763
+ if (tabs.length > 0) {
1764
+ const firstTab = tabs[0];
1765
+ const pt = firstTab != null ? metaStr(firstTab.metadata, "pointsTo") : void 0;
1766
+ rootPointsTo = pt != null ? pointsToSlug(pt) : void 0;
1767
+ } else {
1768
+ const sorted = [...scoped].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1769
+ for (const s of sorted) {
1770
+ if (s.seg.hidden) {
1771
+ continue;
1772
+ }
1773
+ const pt = metaStr(s.seg.metadata, "pointsTo");
1774
+ if (pt != null) {
1775
+ rootPointsTo = pointsToSlug(pt);
1776
+ break;
1777
+ }
1778
+ }
1779
+ }
1669
1780
  }
1670
1781
  const root = {
1671
1782
  type: "root",
@@ -1678,21 +1789,22 @@ function buildFullRootFromSegments(options) {
1678
1789
  return root;
1679
1790
  }
1680
1791
  function uniqueDetails(scoped, dim) {
1681
- const bySlug = /* @__PURE__ */ new Map();
1792
+ const byKey = /* @__PURE__ */ new Map();
1682
1793
  for (const s of scoped) {
1683
1794
  const d = s.seg[dim];
1684
1795
  if (d == null) {
1685
1796
  continue;
1686
1797
  }
1687
1798
  const slug = detailSlug(d);
1688
- const existing = bySlug.get(slug);
1799
+ const key = dim === "tab" ? d.id : slug !== "" ? slug : d.id;
1800
+ const existing = byKey.get(key);
1689
1801
  if (existing == null) {
1690
- bySlug.set(slug, d);
1802
+ byKey.set(key, d);
1691
1803
  } else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
1692
- bySlug.set(slug, d);
1804
+ byKey.set(key, d);
1693
1805
  }
1694
1806
  }
1695
- return [...bySlug.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1807
+ return [...byKey.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1696
1808
  }
1697
1809
  function scopeSlugPrefix(rootSlug, ...details) {
1698
1810
  const parts = [rootSlug];
@@ -1836,16 +1948,71 @@ function buildUnversioned(ctx, scopeSegs, scopePrefix, tabsPresent) {
1836
1948
  type: "unversioned",
1837
1949
  id: ctx.nodeId(`unversioned:${first?.seg.product?.id ?? "root"}`),
1838
1950
  collapsed: void 0,
1839
- landingPage: void 0,
1951
+ landingPage: buildLandingPage(ctx, scopeSegs),
1840
1952
  // The enclosing scope prefix (product slug, or rootSlug at the top
1841
1953
  // level) roots structural sections so they share the scope's slug
1842
1954
  // namespace.
1843
1955
  child: buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix)
1844
1956
  };
1845
1957
  }
1846
- function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1958
+ function mergeSharedSections(defaultSegs, allScoped, defaultVersion, versionSlugs) {
1959
+ const defaultTabsByName = /* @__PURE__ */ new Map();
1960
+ for (const s of defaultSegs) {
1961
+ if (s.seg.tab != null) {
1962
+ const tabName = s.seg.tab.displayName;
1963
+ if (!defaultTabsByName.has(tabName)) {
1964
+ defaultTabsByName.set(tabName, s.seg.tab);
1965
+ }
1966
+ }
1967
+ }
1968
+ const existingSections = new Set(
1969
+ defaultSegs.filter((s) => metaStr(s.seg.metadata, "type") === "section").map((s) => s.seg.section)
1970
+ );
1971
+ const maxSortOrder = defaultSegs.reduce((max, s) => Math.max(max, s.seg.sortOrder), 0);
1972
+ let nextSortOrder = maxSortOrder + 1;
1973
+ const merged = [...defaultSegs];
1974
+ for (const s of allScoped) {
1975
+ if (s.seg.version?.id === defaultVersion.id) {
1976
+ continue;
1977
+ }
1978
+ const type = metaStr(s.seg.metadata, "type");
1979
+ if (type !== "section") {
1980
+ continue;
1981
+ }
1982
+ const sectionPath = s.seg.section;
1983
+ if (versionSlugs.some((vs) => sectionPath === vs || sectionPath.startsWith(vs + "/"))) {
1984
+ continue;
1985
+ }
1986
+ if (existingSections.has(sectionPath)) {
1987
+ continue;
1988
+ }
1989
+ const sourceTabName = s.seg.tab?.displayName ?? "";
1990
+ const targetTab = defaultTabsByName.get(sourceTabName);
1991
+ if (targetTab == null) {
1992
+ continue;
1993
+ }
1994
+ const metadata = s.seg.metadata != null ? { ...s.seg.metadata, childIndex: void 0 } : s.seg.metadata;
1995
+ merged.push({
1996
+ seg: {
1997
+ ...s.seg,
1998
+ tab: targetTab,
1999
+ version: defaultVersion,
2000
+ sortOrder: nextSortOrder++,
2001
+ metadata
2002
+ },
2003
+ nav: s.nav
2004
+ });
2005
+ existingSections.add(sectionPath);
2006
+ }
2007
+ return merged;
2008
+ }
2009
+ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix, skipSharedSectionMerge) {
2010
+ const versionSlugs = versions.map((v) => detailSlug(v)).filter((s) => s !== "");
1847
2011
  const children = versions.map((version) => {
1848
- const versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
2012
+ let versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
2013
+ if (detailIsDefault(version) && !skipSharedSectionMerge) {
2014
+ versionSegs = mergeSharedSections(versionSegs, scoped, version, versionSlugs);
2015
+ }
1849
2016
  const tabsPresent = uniqueDetails(versionSegs, "tab").length > 0;
1850
2017
  const prefix = productPrefix != null ? productPrefix : rootSlug;
1851
2018
  const versionSegment = detailSlug(version);
@@ -1863,7 +2030,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1863
2030
  default: detailIsDefault(version),
1864
2031
  versionId: VersionId(version.id),
1865
2032
  availability: void 0,
1866
- landingPage: buildVersionLandingPage(ctx, versionSegs, asSlug(slug)),
2033
+ landingPage: buildLandingPage(ctx, versionSegs),
1867
2034
  announcement: void 0,
1868
2035
  pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1869
2036
  // The version's full slug roots structural sections so the whole
@@ -1944,34 +2111,41 @@ function crossVersionDedupKeys(node, parents) {
1944
2111
  keys.push([...parentTitles, node.title].join("###"));
1945
2112
  return keys;
1946
2113
  }
1947
- function buildVersionLandingPage(ctx, versionSegs, versionSlug) {
1948
- const tablessSegs = versionSegs.filter((s) => s.seg.tab == null);
1949
- if (tablessSegs.length === 0) {
2114
+ function routeToLandingPage(ctx, route) {
2115
+ if (route == null || route.type !== "markdown" || route.fullPath == null) {
1950
2116
  return void 0;
1951
2117
  }
1952
- for (const s of tablessSegs) {
1953
- for (const r of s.nav) {
1954
- if (r.type === "markdown" && r.fullPath != null) {
1955
- const md = r.metadata;
1956
- const pageId = metaStr(md, "pageId") ?? "";
1957
- const slug = ctx.contentSlug(r.fullPath);
1958
- return {
1959
- type: "landingPage",
1960
- ...withMetadataDefaults({
1961
- id: ctx.nodeId(`landing:${slug}`),
1962
- title: metaStr(md, "title") ?? "",
1963
- slug,
1964
- icon: metaStr(md, "icon"),
1965
- hidden: r.hidden,
1966
- viewers: toViewers(metaStrArr(md, "viewers"))
1967
- }),
1968
- pageId: PageId(pageId),
1969
- noindex: metaBool(md, "noindex")
1970
- };
1971
- }
1972
- }
2118
+ const md = route.metadata;
2119
+ const pageId = metaStr(md, "pageId");
2120
+ if (pageId == null) {
2121
+ return void 0;
1973
2122
  }
1974
- return void 0;
2123
+ const slug = ctx.contentSlug(route.fullPath);
2124
+ return {
2125
+ type: "landingPage",
2126
+ ...withMetadataDefaults({
2127
+ id: ctx.nodeId(`landing:${slug}`),
2128
+ title: metaStr(md, "title") ?? "",
2129
+ slug,
2130
+ icon: metaStr(md, "icon"),
2131
+ hidden: route.hidden,
2132
+ authed: metaBool(md, "authed"),
2133
+ viewers: toViewers(metaStrArr(md, "viewers")),
2134
+ orphaned: metaBool(md, "orphaned"),
2135
+ featureFlags: metaFeatureFlags(md)
2136
+ }),
2137
+ pageId: PageId(pageId),
2138
+ noindex: metaBool(md, "noindex")
2139
+ };
2140
+ }
2141
+ function buildLandingPage(ctx, scopeSegs) {
2142
+ const landingSegment = scopeSegs.find(
2143
+ (s) => metaStr(s.seg.metadata, "type") === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true
2144
+ );
2145
+ return routeToLandingPage(
2146
+ ctx,
2147
+ landingSegment?.nav.find((route) => route.type === "markdown")
2148
+ );
1975
2149
  }
1976
2150
  function markCrossVersionCanonicalSlugs(versionNodes) {
1977
2151
  const keyToCanonical = /* @__PURE__ */ new Map();
@@ -2006,13 +2180,13 @@ function markCrossVersionCanonicalSlugs(versionNodes) {
2006
2180
  });
2007
2181
  }
2008
2182
  }
2009
- function buildProductGroup(ctx, products, scoped, rootSlug) {
2183
+ function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge) {
2010
2184
  const children = products.map((product) => {
2011
2185
  const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
2012
2186
  const versions = uniqueDetails(productSegs, "version");
2013
2187
  const tabsPresent = uniqueDetails(productSegs, "tab").length > 0;
2014
2188
  const productPrefix = scopeSlugPrefix(rootSlug, product);
2015
- const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
2189
+ const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix, skipSharedSectionMerge) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
2016
2190
  const node = {
2017
2191
  type: "product",
2018
2192
  ...withMetadataDefaults({
@@ -2042,7 +2216,10 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
2042
2216
  type: "productgroup",
2043
2217
  id: ctx.nodeId("productgroup"),
2044
2218
  collapsed: void 0,
2045
- landingPage: void 0,
2219
+ landingPage: buildLandingPage(
2220
+ ctx,
2221
+ scoped.filter((s) => s.seg.product == null)
2222
+ ),
2046
2223
  children
2047
2224
  };
2048
2225
  }