@fern-api/fdr-sdk 1.2.38-b6bdd8176d → 1.2.39-008eed59b3

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.
@@ -94,6 +94,9 @@ var AuthSchemeIdSchema = z2.string();
94
94
  var SubpackageIdSchema = z2.string();
95
95
  var WebSocketMessageIdSchema = z2.string();
96
96
  var FileIdSchema = z2.string();
97
+ function FileId(value) {
98
+ return value;
99
+ }
97
100
  var MultipleAuthTypeSchema = z2.object({
98
101
  schemes: z2.array(AuthSchemeIdSchema)
99
102
  });
@@ -657,6 +660,77 @@ function getChildren(node) {
657
660
  }
658
661
  }
659
662
 
663
+ // ../commons/core-utils/dist/assertNever.js
664
+ function assertNever(x) {
665
+ throw new Error("Unexpected value: " + JSON.stringify(x));
666
+ }
667
+
668
+ // ../commons/core-utils/dist/visitDiscriminatedUnion.js
669
+ function visitDiscriminatedUnion(item, discriminant = "type") {
670
+ return {
671
+ _visit: (visitor) => {
672
+ const visit = visitor[item[discriminant]];
673
+ if (visit != null) {
674
+ return visit(item);
675
+ } else {
676
+ if (visitor._other == null) {
677
+ assertNever(item);
678
+ }
679
+ return visitor._other(item);
680
+ }
681
+ }
682
+ };
683
+ }
684
+ var visitDiscriminatedUnion_default = visitDiscriminatedUnion;
685
+
686
+ // src/navigation/versions/latest/getPageId.ts
687
+ var RETURN_PAGEID = (node) => node.pageId;
688
+ var RETURN_OVERVIEW_PAGEID = (node) => node.overviewPageId;
689
+ var RETURN_UNDEFINED = () => void 0;
690
+ function getPageId(node) {
691
+ return visitDiscriminatedUnion_default(node)._visit({
692
+ section: RETURN_OVERVIEW_PAGEID,
693
+ apiReference: RETURN_OVERVIEW_PAGEID,
694
+ changelog: RETURN_OVERVIEW_PAGEID,
695
+ apiPackage: RETURN_OVERVIEW_PAGEID,
696
+ changelogEntry: RETURN_PAGEID,
697
+ page: RETURN_PAGEID,
698
+ landingPage: RETURN_PAGEID,
699
+ // if the following changes, make sure to update the algolia records generator
700
+ endpoint: RETURN_UNDEFINED,
701
+ webSocket: RETURN_UNDEFINED,
702
+ webhook: RETURN_UNDEFINED,
703
+ grpc: RETURN_UNDEFINED,
704
+ graphql: RETURN_UNDEFINED,
705
+ graphqlType: RETURN_UNDEFINED
706
+ // changelogYear: RETURN_UNDEFINED,
707
+ // changelogMonth: RETURN_UNDEFINED,
708
+ });
709
+ }
710
+
711
+ // src/navigation/versions/latest/NavigationNodeSection.ts
712
+ function isSection(node) {
713
+ return node.type === "section" || node.type === "apiReference" || node.type === "changelog" || node.type === "apiPackage";
714
+ }
715
+
716
+ // src/navigation/versions/latest/NavigationNodeSectionOverview.ts
717
+ function isSectionOverview(node) {
718
+ return isSection(node) && node.overviewPageId != null;
719
+ }
720
+
721
+ // src/navigation/versions/latest/NavigationNodeMarkdown.ts
722
+ function hasMarkdown(node) {
723
+ return isMarkdownLeaf(node) || isSectionOverview(node);
724
+ }
725
+
726
+ // src/navigation/versions/latest/NavigationNodePage.ts
727
+ function isPage(node) {
728
+ return isApiLeaf(node) || node.type === "changelog" || // TODO: Uncomment when changelog years and months are visitable
729
+ // node.type === "changelogYear" ||
730
+ // node.type === "changelogMonth" ||
731
+ hasMarkdown(node);
732
+ }
733
+
660
734
  // src/navigation/versions/latest/NavigationNodeWithMetadata.ts
661
735
  function hasMetadata(node) {
662
736
  return typeof node.title === "string" && typeof node.slug === "string";
@@ -794,6 +868,13 @@ function metaStrArr(metadata, key) {
794
868
  }
795
869
  return void 0;
796
870
  }
871
+ function metaFeatureFlags(metadata) {
872
+ if (metadata != null && typeof metadata === "object" && "featureFlags" in metadata) {
873
+ const v = metadata.featureFlags;
874
+ return Array.isArray(v) && v.length > 0 ? v : void 0;
875
+ }
876
+ return void 0;
877
+ }
797
878
  function toViewers(viewers) {
798
879
  if (viewers == null || viewers.length === 0) {
799
880
  return void 0;
@@ -829,17 +910,17 @@ function scopeKey(seg) {
829
910
  return [seg.product?.id ?? "", seg.version?.id ?? "", seg.variant?.id ?? "", seg.tab?.id ?? ""].join("|");
830
911
  }
831
912
  function withMetadataDefaults(base) {
832
- const { viewers, ...rest } = base;
913
+ const { viewers, featureFlags, ...rest } = base;
833
914
  return {
834
915
  ...rest,
835
916
  canonicalSlug: void 0,
836
- authed: void 0,
917
+ authed: base.authed === true ? true : void 0,
837
918
  collapsed: void 0,
838
919
  // Normalise empty arrays to undefined so unrestricted nodes don't add
839
920
  // filter-level noise; a non-empty array engages the RBAC view gate.
840
921
  viewers: viewers != null && viewers.length > 0 ? viewers : void 0,
841
- orphaned: void 0,
842
- featureFlags: void 0
922
+ orphaned: base.orphaned === true ? true : void 0,
923
+ featureFlags: featureFlags != null && featureFlags.length > 0 ? featureFlags : void 0
843
924
  };
844
925
  }
845
926
  function artifactToNode(ctx, route) {
@@ -862,7 +943,10 @@ function artifactToNode(ctx, route) {
862
943
  slug,
863
944
  icon,
864
945
  hidden: route.hidden,
865
- viewers
946
+ authed: metaBool(md, "authed"),
947
+ viewers,
948
+ orphaned: metaBool(md, "orphaned"),
949
+ featureFlags: metaFeatureFlags(md)
866
950
  }),
867
951
  pageId: PageId(pageId),
868
952
  noindex: metaBool(md, "noindex"),
@@ -878,7 +962,7 @@ function artifactToNode(ctx, route) {
878
962
  title,
879
963
  icon,
880
964
  url: Url(metaStr(md, "url") ?? ""),
881
- target: void 0
965
+ target: metaStr(md, "target")
882
966
  };
883
967
  return node;
884
968
  }
@@ -913,7 +997,10 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
913
997
  slug,
914
998
  icon,
915
999
  hidden: route.hidden,
916
- viewers
1000
+ authed: metaBool(md, "authed"),
1001
+ viewers,
1002
+ orphaned: metaBool(md, "orphaned"),
1003
+ featureFlags: metaFeatureFlags(md)
917
1004
  });
918
1005
  if (route.type === "rest") {
919
1006
  const endpointId = metaStr(md, "endpointId");
@@ -928,7 +1015,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
928
1015
  endpointId: EndpointId(endpointId),
929
1016
  apiDefinitionId,
930
1017
  isResponseStream: metaBool(md, "isResponseStream"),
931
- availability: void 0,
1018
+ availability: metaStr(md, "availability"),
932
1019
  playground: void 0
933
1020
  };
934
1021
  }
@@ -944,7 +1031,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
944
1031
  method,
945
1032
  webhookId: WebhookId(webhookId),
946
1033
  apiDefinitionId,
947
- availability: void 0
1034
+ availability: metaStr(md, "availability")
948
1035
  };
949
1036
  }
950
1037
  if (route.type === "asyncapi") {
@@ -957,7 +1044,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
957
1044
  ...meta,
958
1045
  webSocketId: WebSocketId(webSocketId),
959
1046
  apiDefinitionId,
960
- availability: void 0,
1047
+ availability: metaStr(md, "availability"),
961
1048
  playground: void 0
962
1049
  };
963
1050
  }
@@ -973,7 +1060,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
973
1060
  method,
974
1061
  grpcId: GrpcId(grpcId),
975
1062
  apiDefinitionId,
976
- availability: void 0
1063
+ availability: metaStr(md, "availability")
977
1064
  };
978
1065
  }
979
1066
  if (route.type === "graphql") {
@@ -989,7 +1076,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
989
1076
  graphqlOperationId: GraphQlOperationId(graphqlOperationId),
990
1077
  graphqlOperationIds: void 0,
991
1078
  apiDefinitionId,
992
- availability: void 0,
1079
+ availability: metaStr(md, "availability"),
993
1080
  playground: void 0
994
1081
  };
995
1082
  }
@@ -1084,8 +1171,9 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1084
1171
  const { seg, nav } = scoped;
1085
1172
  const overview = overviewRoute(nav) ?? overviewRouteFromSegmentMeta(seg, nav);
1086
1173
  const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
1087
- let slug = structuralNodeSlug(ctx, overview?.fullPath, seg.section, scopePrefix);
1088
- if (seg.section === "" && overview?.fullPath == null) {
1174
+ const relSection = stripLeadingScopePrefix(seg.section, scopePrefix);
1175
+ let slug = structuralNodeSlug(ctx, overview?.fullPath, relSection, scopePrefix);
1176
+ if (relSection === "" && overview?.fullPath == null) {
1089
1177
  slug = inferSectionSlugFromNav(ctx, nav, scopePrefix) ?? slug;
1090
1178
  }
1091
1179
  const metaPointsTo = metaStr(seg.metadata, "pointsTo");
@@ -1095,17 +1183,22 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1095
1183
  slug,
1096
1184
  icon: metaStr(seg.metadata, "icon"),
1097
1185
  hidden: seg.hidden,
1098
- viewers: mergeVariantViewers(seg)
1186
+ authed: metaBool(seg.metadata, "authed"),
1187
+ viewers: mergeVariantViewers(seg),
1188
+ orphaned: metaBool(seg.metadata, "orphaned"),
1189
+ featureFlags: metaFeatureFlags(seg.metadata)
1099
1190
  });
1100
1191
  return {
1101
1192
  type: "section",
1102
1193
  ...defaults,
1103
- collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1194
+ // V2 convention: collapsed:false in docs.yml maps to "open-by-default"
1195
+ // so getInitiallyOpenByDefaultNodes picks it up and the UI starts open.
1196
+ collapsed: metaCollapsed(seg.metadata) === false ? "open-by-default" : metaCollapsed(seg.metadata) ?? defaults.collapsed,
1104
1197
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1105
- noindex: void 0,
1198
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1106
1199
  collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
1107
1200
  collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1108
- availability: void 0,
1201
+ availability: metaStr(seg.metadata, "availability"),
1109
1202
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1110
1203
  children: mergeChildrenByPosition(ctx, nav, sectionChildren)
1111
1204
  };
@@ -1166,7 +1259,12 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
1166
1259
  const overview = overviewRoute(nav);
1167
1260
  const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
1168
1261
  const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? parentApiDefinitionId;
1169
- const slug = structuralNodeSlug(ctx, overview?.fullPath, seg.section, scopePrefix);
1262
+ const slug = structuralNodeSlug(
1263
+ ctx,
1264
+ overview?.fullPath,
1265
+ stripLeadingScopePrefix(seg.section, scopePrefix),
1266
+ scopePrefix
1267
+ );
1170
1268
  const metaPointsTo = metaStr(seg.metadata, "pointsTo");
1171
1269
  const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
1172
1270
  return {
@@ -1177,12 +1275,15 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
1177
1275
  slug,
1178
1276
  icon: metaStr(seg.metadata, "icon"),
1179
1277
  hidden: seg.hidden,
1180
- viewers: toViewers(metaStrArr(seg.metadata, "viewers"))
1278
+ authed: metaBool(seg.metadata, "authed"),
1279
+ viewers: toViewers(metaStrArr(seg.metadata, "viewers")),
1280
+ orphaned: metaBool(seg.metadata, "orphaned"),
1281
+ featureFlags: metaFeatureFlags(seg.metadata)
1181
1282
  }),
1182
1283
  apiDefinitionId: ApiDefinitionId(apiDefinitionId),
1183
1284
  availability: metaStr(seg.metadata, "availability"),
1184
1285
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1185
- noindex: void 0,
1286
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1186
1287
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1187
1288
  children,
1188
1289
  playground: void 0
@@ -1245,7 +1346,12 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
1245
1346
  const overview = overviewRoute(nav);
1246
1347
  const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
1247
1348
  const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? "";
1248
- const slug = structuralNodeSlug(ctx, overview?.fullPath, seg.section, scopePrefix);
1349
+ const slug = structuralNodeSlug(
1350
+ ctx,
1351
+ overview?.fullPath,
1352
+ stripLeadingScopePrefix(seg.section, scopePrefix),
1353
+ scopePrefix
1354
+ );
1249
1355
  const metaPointsTo = metaStr(seg.metadata, "pointsTo");
1250
1356
  const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
1251
1357
  const changelog = attachedApiChangelogNode(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
@@ -1257,12 +1363,15 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
1257
1363
  slug,
1258
1364
  icon: metaStr(seg.metadata, "icon"),
1259
1365
  hidden: seg.hidden,
1260
- viewers: mergeVariantViewers(seg)
1366
+ authed: metaBool(seg.metadata, "authed"),
1367
+ viewers: mergeVariantViewers(seg),
1368
+ orphaned: metaBool(seg.metadata, "orphaned"),
1369
+ featureFlags: metaFeatureFlags(seg.metadata)
1261
1370
  }),
1262
1371
  apiDefinitionId: ApiDefinitionId(apiDefinitionId),
1263
- availability: void 0,
1372
+ availability: metaStr(seg.metadata, "availability"),
1264
1373
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1265
- noindex: void 0,
1374
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1266
1375
  paginated: true,
1267
1376
  showErrors: metaBool(seg.metadata, "showErrors"),
1268
1377
  hideTitle: metaBool(seg.metadata, "hideTitle"),
@@ -1315,10 +1424,13 @@ function changelogNode(ctx, scoped, scopePrefix) {
1315
1424
  slug: ctx.contentSlug(r.fullPath ?? ""),
1316
1425
  icon: metaStr(r.metadata, "icon"),
1317
1426
  hidden: r.hidden,
1318
- viewers: toViewers(metaStrArr(r.metadata, "viewers"))
1427
+ authed: metaBool(r.metadata, "authed"),
1428
+ viewers: toViewers(metaStrArr(r.metadata, "viewers")),
1429
+ orphaned: metaBool(r.metadata, "orphaned"),
1430
+ featureFlags: metaFeatureFlags(r.metadata)
1319
1431
  }),
1320
1432
  pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
1321
- noindex: void 0,
1433
+ noindex: metaBool(r.metadata, "noindex"),
1322
1434
  date: dateStr ?? "",
1323
1435
  tags: void 0
1324
1436
  };
@@ -1364,10 +1476,13 @@ function changelogNode(ctx, scoped, scopePrefix) {
1364
1476
  slug: baseSlug,
1365
1477
  icon: metaStr(seg.metadata, "icon"),
1366
1478
  hidden: seg.hidden,
1367
- viewers: mergeVariantViewers(seg)
1479
+ authed: metaBool(seg.metadata, "authed"),
1480
+ viewers: mergeVariantViewers(seg),
1481
+ orphaned: metaBool(seg.metadata, "orphaned"),
1482
+ featureFlags: metaFeatureFlags(seg.metadata)
1368
1483
  }),
1369
1484
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1370
- noindex: void 0,
1485
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1371
1486
  children: years
1372
1487
  };
1373
1488
  }
@@ -1553,6 +1668,24 @@ function buildFullRootFromSegments(options) {
1553
1668
  } else if (child.type === "versioned") {
1554
1669
  const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
1555
1670
  rootPointsTo = defaultVersion?.pointsTo;
1671
+ } else if (child.type === "unversioned") {
1672
+ if (tabs.length > 0) {
1673
+ const firstTab = tabs[0];
1674
+ const pt = firstTab != null ? metaStr(firstTab.metadata, "pointsTo") : void 0;
1675
+ rootPointsTo = pt != null ? pointsToSlug(pt) : void 0;
1676
+ } else {
1677
+ const sorted = [...scoped].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1678
+ for (const s of sorted) {
1679
+ if (s.seg.hidden) {
1680
+ continue;
1681
+ }
1682
+ const pt = metaStr(s.seg.metadata, "pointsTo");
1683
+ if (pt != null) {
1684
+ rootPointsTo = pointsToSlug(pt);
1685
+ break;
1686
+ }
1687
+ }
1688
+ }
1556
1689
  }
1557
1690
  const root = {
1558
1691
  type: "root",
@@ -1565,21 +1698,22 @@ function buildFullRootFromSegments(options) {
1565
1698
  return root;
1566
1699
  }
1567
1700
  function uniqueDetails(scoped, dim) {
1568
- const bySlug = /* @__PURE__ */ new Map();
1701
+ const byKey = /* @__PURE__ */ new Map();
1569
1702
  for (const s of scoped) {
1570
1703
  const d = s.seg[dim];
1571
1704
  if (d == null) {
1572
1705
  continue;
1573
1706
  }
1574
1707
  const slug = detailSlug(d);
1575
- const existing = bySlug.get(slug);
1708
+ const key = slug !== "" ? slug : d.id;
1709
+ const existing = byKey.get(key);
1576
1710
  if (existing == null) {
1577
- bySlug.set(slug, d);
1711
+ byKey.set(key, d);
1578
1712
  } else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
1579
- bySlug.set(slug, d);
1713
+ byKey.set(key, d);
1580
1714
  }
1581
1715
  }
1582
- return [...bySlug.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1716
+ return [...byKey.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1583
1717
  }
1584
1718
  function scopeSlugPrefix(rootSlug, ...details) {
1585
1719
  const parts = [rootSlug];
@@ -1613,7 +1747,7 @@ function buildVariantedNode(ctx, variants, scopeSegs, scopePrefix) {
1613
1747
  default: detailIsDefault(variant),
1614
1748
  variantId: VariantId(String(variant.id)),
1615
1749
  subtitle: metaStr(variant.metadata, "subtitle") ?? void 0,
1616
- image: void 0,
1750
+ image: metaStr(variant.metadata, "image") != null ? FileId(metaStr(variant.metadata, "image")) : void 0,
1617
1751
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1618
1752
  children
1619
1753
  };
@@ -1650,7 +1784,10 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix) {
1650
1784
  const tabDetails = uniqueDetails(scopeSegs, "tab");
1651
1785
  const children = tabDetails.map((tab) => {
1652
1786
  const tabType = metaStr(tab.metadata, "tab_type");
1653
- const tabSlug = asSlug(scopeSlugPrefix(scopePrefix, tab));
1787
+ const rawTabSlug = detailSlug(tab);
1788
+ const versionDetail = scopeSegs[0]?.seg.version;
1789
+ const versionSlugStr = versionDetail != null ? detailSlug(versionDetail) : void 0;
1790
+ const tabSlug = versionSlugStr != null && rawTabSlug !== "" && (rawTabSlug === versionSlugStr || rawTabSlug.startsWith(versionSlugStr + "/")) ? asSlug(rawTabSlug) : asSlug(scopeSlugPrefix(scopePrefix, tab));
1654
1791
  if (tabType === "link") {
1655
1792
  return {
1656
1793
  type: "link",
@@ -1659,7 +1796,7 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix) {
1659
1796
  title: tab.displayName,
1660
1797
  icon: tab.icon ?? void 0,
1661
1798
  url: Url(metaStr(tab.metadata, "url") ?? ""),
1662
- target: void 0
1799
+ target: metaStr(tab.metadata, "target")
1663
1800
  };
1664
1801
  }
1665
1802
  if (tabType === "changelog") {
@@ -1747,7 +1884,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1747
1884
  default: detailIsDefault(version),
1748
1885
  versionId: VersionId(version.id),
1749
1886
  availability: void 0,
1750
- landingPage: void 0,
1887
+ landingPage: buildVersionLandingPage(ctx, versionSegs, asSlug(slug)),
1751
1888
  announcement: void 0,
1752
1889
  pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1753
1890
  // The version's full slug roots structural sections so the whole
@@ -1759,6 +1896,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1759
1896
  }
1760
1897
  return node;
1761
1898
  });
1899
+ markCrossVersionCanonicalSlugs(children);
1762
1900
  return {
1763
1901
  type: "versioned",
1764
1902
  id: ctx.nodeId(`versioned:${productPrefix ?? "root"}`),
@@ -1784,6 +1922,111 @@ function markDefaultVersionCanonicalSlugs(node, pruneSlug, versionSlug) {
1784
1922
  return;
1785
1923
  });
1786
1924
  }
1925
+ function unversionedParents(parents) {
1926
+ let versionIdx = -1;
1927
+ for (let i = parents.length - 1; i >= 0; i--) {
1928
+ if (parents[i].type === "version") {
1929
+ versionIdx = i;
1930
+ break;
1931
+ }
1932
+ }
1933
+ return versionIdx >= 0 ? parents.slice(versionIdx + 1) : parents;
1934
+ }
1935
+ function crossVersionDedupKeys(node, parents) {
1936
+ const keys = [];
1937
+ const uParents = unversionedParents(parents);
1938
+ const pid = getPageId(node);
1939
+ if (pid != null) {
1940
+ keys.push(`pid:${pid}`);
1941
+ }
1942
+ if (node.type === "endpoint" || node.type === "webSocket" || node.type === "webhook" || node.type === "grpc" || node.type === "graphql") {
1943
+ const apiParentTitles = uParents.filter(
1944
+ (p) => p.type === "apiReference"
1945
+ ).map((p) => p.title.replaceAll(" ", ""));
1946
+ const apiPrefix = apiParentTitles.join(":");
1947
+ if (node.type === "endpoint") {
1948
+ keys.push(`${apiPrefix}:api:endpoint:${node.method}:${node.endpointId}`);
1949
+ } else if (node.type === "webSocket") {
1950
+ keys.push(`${apiPrefix}:api:websocket:${node.webSocketId}`);
1951
+ } else if (node.type === "webhook") {
1952
+ keys.push(`${apiPrefix}:api:webhook:${node.method}:${node.webhookId}`);
1953
+ } else if (node.type === "grpc") {
1954
+ keys.push(`${apiPrefix}:api:grpc:${node.method}:${node.grpcId}`);
1955
+ } else if (node.type === "graphql") {
1956
+ keys.push(`${apiPrefix}:api:graphql:${node.id}`);
1957
+ }
1958
+ }
1959
+ const parentTitles = [];
1960
+ for (const p of uParents) {
1961
+ if (hasMetadata(p)) {
1962
+ parentTitles.push(p.title);
1963
+ }
1964
+ }
1965
+ keys.push([...parentTitles, node.title].join("###"));
1966
+ return keys;
1967
+ }
1968
+ function buildVersionLandingPage(ctx, versionSegs, versionSlug) {
1969
+ const tablessSegs = versionSegs.filter((s) => s.seg.tab == null);
1970
+ if (tablessSegs.length === 0) {
1971
+ return void 0;
1972
+ }
1973
+ for (const s of tablessSegs) {
1974
+ for (const r of s.nav) {
1975
+ if (r.type === "markdown" && r.fullPath != null) {
1976
+ const md = r.metadata;
1977
+ const pageId = metaStr(md, "pageId") ?? "";
1978
+ const slug = ctx.contentSlug(r.fullPath);
1979
+ return {
1980
+ type: "landingPage",
1981
+ ...withMetadataDefaults({
1982
+ id: ctx.nodeId(`landing:${slug}`),
1983
+ title: metaStr(md, "title") ?? "",
1984
+ slug,
1985
+ icon: metaStr(md, "icon"),
1986
+ hidden: r.hidden,
1987
+ viewers: toViewers(metaStrArr(md, "viewers"))
1988
+ }),
1989
+ pageId: PageId(pageId),
1990
+ noindex: metaBool(md, "noindex")
1991
+ };
1992
+ }
1993
+ }
1994
+ }
1995
+ return void 0;
1996
+ }
1997
+ function markCrossVersionCanonicalSlugs(versionNodes) {
1998
+ const keyToCanonical = /* @__PURE__ */ new Map();
1999
+ const sorted = [...versionNodes].sort((a, b) => {
2000
+ if (a.default !== b.default) {
2001
+ return a.default ? -1 : 1;
2002
+ }
2003
+ return 0;
2004
+ });
2005
+ for (const version of sorted) {
2006
+ traverseDF(version, (child, parents) => {
2007
+ if (hasMetadata(child) && isPage(child)) {
2008
+ const keys = crossVersionDedupKeys(child, parents);
2009
+ let matched = false;
2010
+ for (const key of keys) {
2011
+ const canonical = keyToCanonical.get(key);
2012
+ if (canonical != null && !version.default) {
2013
+ child.canonicalSlug = canonical;
2014
+ matched = true;
2015
+ break;
2016
+ }
2017
+ }
2018
+ if (!matched) {
2019
+ const canonical = child.canonicalSlug ?? child.slug;
2020
+ for (const key of keys) {
2021
+ if (!keyToCanonical.has(key)) {
2022
+ keyToCanonical.set(key, canonical);
2023
+ }
2024
+ }
2025
+ }
2026
+ }
2027
+ });
2028
+ }
2029
+ }
1787
2030
  function buildProductGroup(ctx, products, scoped, rootSlug) {
1788
2031
  const children = products.map((product) => {
1789
2032
  const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
@@ -1809,7 +2052,7 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
1809
2052
  // here; sourcing it from the hash makes that filter match nothing.
1810
2053
  productId: ProductId(product.displayName),
1811
2054
  subtitle: metaStr(product.metadata, "subtitle") ?? "",
1812
- image: void 0,
2055
+ image: metaStr(product.metadata, "image") != null ? FileId(metaStr(product.metadata, "image")) : void 0,
1813
2056
  announcement: void 0,
1814
2057
  pointsTo: metaStr(product.metadata, "pointsTo") != null ? pointsToSlug(metaStr(product.metadata, "pointsTo")) : void 0,
1815
2058
  child: productChild