@fern-api/fdr-sdk 1.2.39-38c6f9a29c → 1.2.39-4a89db5dd2

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 (34) hide show
  1. package/dist/js/client/FdrClient.js +28 -7
  2. package/dist/js/client/FdrClient.js.map +1 -1
  3. package/dist/js/client/FdrClient.mjs +28 -7
  4. package/dist/js/client/FdrClient.mjs.map +1 -1
  5. package/dist/js/index.js +28 -7
  6. package/dist/js/index.js.map +1 -1
  7. package/dist/js/index.mjs +28 -7
  8. package/dist/js/index.mjs.map +1 -1
  9. package/dist/js/navigation/ledger-root-builder.js +188 -75
  10. package/dist/js/navigation/ledger-root-builder.js.map +1 -1
  11. package/dist/js/navigation/ledger-root-builder.mjs +188 -75
  12. package/dist/js/navigation/ledger-root-builder.mjs.map +1 -1
  13. package/dist/js/orpc-client.js +30 -7
  14. package/dist/js/orpc-client.js.map +1 -1
  15. package/dist/js/orpc-client.mjs +30 -7
  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.rootSlug.test.d.ts +2 -0
  23. package/dist/types/navigation/__test__/ledger-root-builder.rootSlug.test.d.ts.map +1 -0
  24. package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts +2 -0
  25. package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts.map +1 -0
  26. package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts +2 -0
  27. package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts.map +1 -0
  28. package/dist/types/navigation/ledger-root-builder.d.ts +2 -0
  29. package/dist/types/navigation/ledger-root-builder.d.ts.map +1 -1
  30. package/dist/types/orpc-client/docs-ledger/contract.d.ts +2190 -170
  31. package/dist/types/orpc-client/docs-ledger/contract.d.ts.map +1 -1
  32. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts +3456 -104
  33. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts.map +1 -1
  34. package/package.json +1 -1
@@ -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
  });
@@ -865,6 +868,13 @@ function metaStrArr(metadata, key) {
865
868
  }
866
869
  return void 0;
867
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
+ }
868
878
  function toViewers(viewers) {
869
879
  if (viewers == null || viewers.length === 0) {
870
880
  return void 0;
@@ -900,17 +910,17 @@ function scopeKey(seg) {
900
910
  return [seg.product?.id ?? "", seg.version?.id ?? "", seg.variant?.id ?? "", seg.tab?.id ?? ""].join("|");
901
911
  }
902
912
  function withMetadataDefaults(base) {
903
- const { viewers, ...rest } = base;
913
+ const { viewers, featureFlags, ...rest } = base;
904
914
  return {
905
915
  ...rest,
906
916
  canonicalSlug: void 0,
907
- authed: void 0,
917
+ authed: base.authed === true ? true : void 0,
908
918
  collapsed: void 0,
909
919
  // Normalise empty arrays to undefined so unrestricted nodes don't add
910
920
  // filter-level noise; a non-empty array engages the RBAC view gate.
911
921
  viewers: viewers != null && viewers.length > 0 ? viewers : void 0,
912
- orphaned: void 0,
913
- featureFlags: void 0
922
+ orphaned: base.orphaned === true ? true : void 0,
923
+ featureFlags: featureFlags != null && featureFlags.length > 0 ? featureFlags : void 0
914
924
  };
915
925
  }
916
926
  function artifactToNode(ctx, route) {
@@ -933,7 +943,10 @@ function artifactToNode(ctx, route) {
933
943
  slug,
934
944
  icon,
935
945
  hidden: route.hidden,
936
- viewers
946
+ authed: metaBool(md, "authed"),
947
+ viewers,
948
+ orphaned: metaBool(md, "orphaned"),
949
+ featureFlags: metaFeatureFlags(md)
937
950
  }),
938
951
  pageId: PageId(pageId),
939
952
  noindex: metaBool(md, "noindex"),
@@ -949,7 +962,7 @@ function artifactToNode(ctx, route) {
949
962
  title,
950
963
  icon,
951
964
  url: Url(metaStr(md, "url") ?? ""),
952
- target: void 0
965
+ target: metaStr(md, "target")
953
966
  };
954
967
  return node;
955
968
  }
@@ -984,7 +997,10 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
984
997
  slug,
985
998
  icon,
986
999
  hidden: route.hidden,
987
- viewers
1000
+ authed: metaBool(md, "authed"),
1001
+ viewers,
1002
+ orphaned: metaBool(md, "orphaned"),
1003
+ featureFlags: metaFeatureFlags(md)
988
1004
  });
989
1005
  if (route.type === "rest") {
990
1006
  const endpointId = metaStr(md, "endpointId");
@@ -999,7 +1015,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
999
1015
  endpointId: EndpointId(endpointId),
1000
1016
  apiDefinitionId,
1001
1017
  isResponseStream: metaBool(md, "isResponseStream"),
1002
- availability: void 0,
1018
+ availability: metaStr(md, "availability"),
1003
1019
  playground: void 0
1004
1020
  };
1005
1021
  }
@@ -1015,7 +1031,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1015
1031
  method,
1016
1032
  webhookId: WebhookId(webhookId),
1017
1033
  apiDefinitionId,
1018
- availability: void 0
1034
+ availability: metaStr(md, "availability")
1019
1035
  };
1020
1036
  }
1021
1037
  if (route.type === "asyncapi") {
@@ -1028,7 +1044,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1028
1044
  ...meta,
1029
1045
  webSocketId: WebSocketId(webSocketId),
1030
1046
  apiDefinitionId,
1031
- availability: void 0,
1047
+ availability: metaStr(md, "availability"),
1032
1048
  playground: void 0
1033
1049
  };
1034
1050
  }
@@ -1044,7 +1060,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1044
1060
  method,
1045
1061
  grpcId: GrpcId(grpcId),
1046
1062
  apiDefinitionId,
1047
- availability: void 0
1063
+ availability: metaStr(md, "availability")
1048
1064
  };
1049
1065
  }
1050
1066
  if (route.type === "graphql") {
@@ -1060,12 +1076,69 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1060
1076
  graphqlOperationId: GraphQlOperationId(graphqlOperationId),
1061
1077
  graphqlOperationIds: void 0,
1062
1078
  apiDefinitionId,
1063
- availability: void 0,
1079
+ availability: metaStr(md, "availability"),
1064
1080
  playground: void 0
1065
1081
  };
1066
1082
  }
1067
1083
  return void 0;
1068
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
+ }
1069
1142
  function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefinitionId2) {
1070
1143
  const ctx = createBuildContext(basePath);
1071
1144
  return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2)).filter((node) => node != null);
@@ -1167,17 +1240,22 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1167
1240
  slug,
1168
1241
  icon: metaStr(seg.metadata, "icon"),
1169
1242
  hidden: seg.hidden,
1170
- viewers: mergeVariantViewers(seg)
1243
+ authed: metaBool(seg.metadata, "authed"),
1244
+ viewers: mergeVariantViewers(seg),
1245
+ orphaned: metaBool(seg.metadata, "orphaned"),
1246
+ featureFlags: metaFeatureFlags(seg.metadata)
1171
1247
  });
1172
1248
  return {
1173
1249
  type: "section",
1174
1250
  ...defaults,
1175
- collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1251
+ // V2 convention: collapsed:false in docs.yml maps to "open-by-default"
1252
+ // so getInitiallyOpenByDefaultNodes picks it up and the UI starts open.
1253
+ collapsed: metaCollapsed(seg.metadata) === false ? "open-by-default" : metaCollapsed(seg.metadata) ?? defaults.collapsed,
1176
1254
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1177
- noindex: void 0,
1255
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1178
1256
  collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
1179
1257
  collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1180
- availability: void 0,
1258
+ availability: metaStr(seg.metadata, "availability"),
1181
1259
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1182
1260
  children: mergeChildrenByPosition(ctx, nav, sectionChildren)
1183
1261
  };
@@ -1200,8 +1278,7 @@ function directChildApiPackages(parentSection, scopeSegs) {
1200
1278
  }
1201
1279
  function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix) {
1202
1280
  const { seg, nav } = scoped;
1203
- const rawLeafNodes = nav.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId)).filter((node) => node != null);
1204
- const leafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
1281
+ const leafNodes = positionedApiLeafChildren(ctx, nav, apiDefinitionId);
1205
1282
  const childPackages = directChildApiPackages(seg.section, scopeSegs);
1206
1283
  const packageNodes = childPackages.map((child) => ({
1207
1284
  node: apiPackageChildNode(
@@ -1215,18 +1292,10 @@ function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix)
1215
1292
  }));
1216
1293
  const hasChildIndex = packageNodes.some((p) => p.childIndex != null);
1217
1294
  if (!hasChildIndex) {
1218
- return [...leafNodes, ...packageNodes.map((p) => p.node)];
1219
- }
1220
- const leafPositions = [];
1221
- for (const route of nav) {
1222
- if (route.displaySortOrder != null) {
1223
- leafPositions.push(route.displaySortOrder);
1224
- }
1295
+ return [...leafNodes, ...packageNodes.map((p) => ({ node: p.node, pos: Number.MAX_SAFE_INTEGER }))].sort((a, b) => a.pos - b.pos).map((p) => p.node);
1225
1296
  }
1226
1297
  const positioned = [];
1227
- for (let i = 0; i < leafNodes.length; i++) {
1228
- positioned.push({ node: leafNodes[i], pos: leafPositions[i] ?? i });
1229
- }
1298
+ positioned.push(...leafNodes);
1230
1299
  for (const p of packageNodes) {
1231
1300
  positioned.push({ node: p.node, pos: p.childIndex ?? Number.MAX_SAFE_INTEGER });
1232
1301
  }
@@ -1254,12 +1323,15 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
1254
1323
  slug,
1255
1324
  icon: metaStr(seg.metadata, "icon"),
1256
1325
  hidden: seg.hidden,
1257
- viewers: toViewers(metaStrArr(seg.metadata, "viewers"))
1326
+ authed: metaBool(seg.metadata, "authed"),
1327
+ viewers: toViewers(metaStrArr(seg.metadata, "viewers")),
1328
+ orphaned: metaBool(seg.metadata, "orphaned"),
1329
+ featureFlags: metaFeatureFlags(seg.metadata)
1258
1330
  }),
1259
1331
  apiDefinitionId: ApiDefinitionId(apiDefinitionId),
1260
1332
  availability: metaStr(seg.metadata, "availability"),
1261
1333
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1262
- noindex: void 0,
1334
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1263
1335
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1264
1336
  children,
1265
1337
  playground: void 0
@@ -1339,12 +1411,15 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
1339
1411
  slug,
1340
1412
  icon: metaStr(seg.metadata, "icon"),
1341
1413
  hidden: seg.hidden,
1342
- viewers: mergeVariantViewers(seg)
1414
+ authed: metaBool(seg.metadata, "authed"),
1415
+ viewers: mergeVariantViewers(seg),
1416
+ orphaned: metaBool(seg.metadata, "orphaned"),
1417
+ featureFlags: metaFeatureFlags(seg.metadata)
1343
1418
  }),
1344
1419
  apiDefinitionId: ApiDefinitionId(apiDefinitionId),
1345
- availability: void 0,
1420
+ availability: metaStr(seg.metadata, "availability"),
1346
1421
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1347
- noindex: void 0,
1422
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1348
1423
  paginated: true,
1349
1424
  showErrors: metaBool(seg.metadata, "showErrors"),
1350
1425
  hideTitle: metaBool(seg.metadata, "hideTitle"),
@@ -1397,10 +1472,13 @@ function changelogNode(ctx, scoped, scopePrefix) {
1397
1472
  slug: ctx.contentSlug(r.fullPath ?? ""),
1398
1473
  icon: metaStr(r.metadata, "icon"),
1399
1474
  hidden: r.hidden,
1400
- viewers: toViewers(metaStrArr(r.metadata, "viewers"))
1475
+ authed: metaBool(r.metadata, "authed"),
1476
+ viewers: toViewers(metaStrArr(r.metadata, "viewers")),
1477
+ orphaned: metaBool(r.metadata, "orphaned"),
1478
+ featureFlags: metaFeatureFlags(r.metadata)
1401
1479
  }),
1402
1480
  pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
1403
- noindex: void 0,
1481
+ noindex: metaBool(r.metadata, "noindex"),
1404
1482
  date: dateStr ?? "",
1405
1483
  tags: void 0
1406
1484
  };
@@ -1446,10 +1524,13 @@ function changelogNode(ctx, scoped, scopePrefix) {
1446
1524
  slug: baseSlug,
1447
1525
  icon: metaStr(seg.metadata, "icon"),
1448
1526
  hidden: seg.hidden,
1449
- viewers: mergeVariantViewers(seg)
1527
+ authed: metaBool(seg.metadata, "authed"),
1528
+ viewers: mergeVariantViewers(seg),
1529
+ orphaned: metaBool(seg.metadata, "orphaned"),
1530
+ featureFlags: metaFeatureFlags(seg.metadata)
1450
1531
  }),
1451
1532
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1452
- noindex: void 0,
1533
+ noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1453
1534
  children: years
1454
1535
  };
1455
1536
  }
@@ -1517,6 +1598,9 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
1517
1598
  if (hasOwningApiReference(s, scopeSegs)) {
1518
1599
  continue;
1519
1600
  }
1601
+ if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
1602
+ continue;
1603
+ }
1520
1604
  if (type === "tabRoot" || sec === "" && type !== "section") {
1521
1605
  for (const r of s.nav) {
1522
1606
  const node = artifactToNode(ctx, r);
@@ -1603,13 +1687,13 @@ function buildSidebarRoot(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1603
1687
  };
1604
1688
  }
1605
1689
  function buildFullRootFromSegments(options) {
1606
- const { basePath, title, segments, navBySegment } = options;
1690
+ const { basePath, rootSlug: sourceRootSlug, title, segments, navBySegment } = options;
1607
1691
  const ctx = createBuildContext(basePath);
1608
1692
  const scoped = segments.filter((seg) => {
1609
1693
  const t = metaStr(seg.metadata, "type");
1610
1694
  return t !== "files" && t !== "redirects";
1611
1695
  }).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
1612
- const rootSlug = asSlug(basePath);
1696
+ const rootSlug = asSlug(sourceRootSlug ?? basePath);
1613
1697
  const scopesByKey = /* @__PURE__ */ new Map();
1614
1698
  for (const s of scoped) {
1615
1699
  const key = scopeKey(s.seg);
@@ -1635,6 +1719,24 @@ function buildFullRootFromSegments(options) {
1635
1719
  } else if (child.type === "versioned") {
1636
1720
  const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
1637
1721
  rootPointsTo = defaultVersion?.pointsTo;
1722
+ } else if (child.type === "unversioned") {
1723
+ if (tabs.length > 0) {
1724
+ const firstTab = tabs[0];
1725
+ const pt = firstTab != null ? metaStr(firstTab.metadata, "pointsTo") : void 0;
1726
+ rootPointsTo = pt != null ? pointsToSlug(pt) : void 0;
1727
+ } else {
1728
+ const sorted = [...scoped].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1729
+ for (const s of sorted) {
1730
+ if (s.seg.hidden) {
1731
+ continue;
1732
+ }
1733
+ const pt = metaStr(s.seg.metadata, "pointsTo");
1734
+ if (pt != null) {
1735
+ rootPointsTo = pointsToSlug(pt);
1736
+ break;
1737
+ }
1738
+ }
1739
+ }
1638
1740
  }
1639
1741
  const root = {
1640
1742
  type: "root",
@@ -1647,21 +1749,22 @@ function buildFullRootFromSegments(options) {
1647
1749
  return root;
1648
1750
  }
1649
1751
  function uniqueDetails(scoped, dim) {
1650
- const bySlug = /* @__PURE__ */ new Map();
1752
+ const byKey = /* @__PURE__ */ new Map();
1651
1753
  for (const s of scoped) {
1652
1754
  const d = s.seg[dim];
1653
1755
  if (d == null) {
1654
1756
  continue;
1655
1757
  }
1656
1758
  const slug = detailSlug(d);
1657
- const existing = bySlug.get(slug);
1759
+ const key = dim === "tab" ? d.id : slug !== "" ? slug : d.id;
1760
+ const existing = byKey.get(key);
1658
1761
  if (existing == null) {
1659
- bySlug.set(slug, d);
1762
+ byKey.set(key, d);
1660
1763
  } else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
1661
- bySlug.set(slug, d);
1764
+ byKey.set(key, d);
1662
1765
  }
1663
1766
  }
1664
- return [...bySlug.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1767
+ return [...byKey.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1665
1768
  }
1666
1769
  function scopeSlugPrefix(rootSlug, ...details) {
1667
1770
  const parts = [rootSlug];
@@ -1695,7 +1798,7 @@ function buildVariantedNode(ctx, variants, scopeSegs, scopePrefix) {
1695
1798
  default: detailIsDefault(variant),
1696
1799
  variantId: VariantId(String(variant.id)),
1697
1800
  subtitle: metaStr(variant.metadata, "subtitle") ?? void 0,
1698
- image: void 0,
1801
+ image: metaStr(variant.metadata, "image") != null ? FileId(metaStr(variant.metadata, "image")) : void 0,
1699
1802
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
1700
1803
  children
1701
1804
  };
@@ -1744,7 +1847,7 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix) {
1744
1847
  title: tab.displayName,
1745
1848
  icon: tab.icon ?? void 0,
1746
1849
  url: Url(metaStr(tab.metadata, "url") ?? ""),
1747
- target: void 0
1850
+ target: metaStr(tab.metadata, "target")
1748
1851
  };
1749
1852
  }
1750
1853
  if (tabType === "changelog") {
@@ -1805,7 +1908,7 @@ function buildUnversioned(ctx, scopeSegs, scopePrefix, tabsPresent) {
1805
1908
  type: "unversioned",
1806
1909
  id: ctx.nodeId(`unversioned:${first?.seg.product?.id ?? "root"}`),
1807
1910
  collapsed: void 0,
1808
- landingPage: void 0,
1911
+ landingPage: buildLandingPage(ctx, scopeSegs),
1809
1912
  // The enclosing scope prefix (product slug, or rootSlug at the top
1810
1913
  // level) roots structural sections so they share the scope's slug
1811
1914
  // namespace.
@@ -1832,7 +1935,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1832
1935
  default: detailIsDefault(version),
1833
1936
  versionId: VersionId(version.id),
1834
1937
  availability: void 0,
1835
- landingPage: buildVersionLandingPage(ctx, versionSegs, asSlug(slug)),
1938
+ landingPage: buildLandingPage(ctx, versionSegs),
1836
1939
  announcement: void 0,
1837
1940
  pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1838
1941
  // The version's full slug roots structural sections so the whole
@@ -1913,34 +2016,41 @@ function crossVersionDedupKeys(node, parents) {
1913
2016
  keys.push([...parentTitles, node.title].join("###"));
1914
2017
  return keys;
1915
2018
  }
1916
- function buildVersionLandingPage(ctx, versionSegs, versionSlug) {
1917
- const tablessSegs = versionSegs.filter((s) => s.seg.tab == null);
1918
- if (tablessSegs.length === 0) {
2019
+ function routeToLandingPage(ctx, route) {
2020
+ if (route == null || route.type !== "markdown" || route.fullPath == null) {
1919
2021
  return void 0;
1920
2022
  }
1921
- for (const s of tablessSegs) {
1922
- for (const r of s.nav) {
1923
- if (r.type === "markdown" && r.fullPath != null) {
1924
- const md = r.metadata;
1925
- const pageId = metaStr(md, "pageId") ?? "";
1926
- const slug = ctx.contentSlug(r.fullPath);
1927
- return {
1928
- type: "landingPage",
1929
- ...withMetadataDefaults({
1930
- id: ctx.nodeId(`landing:${slug}`),
1931
- title: metaStr(md, "title") ?? "",
1932
- slug,
1933
- icon: metaStr(md, "icon"),
1934
- hidden: r.hidden,
1935
- viewers: toViewers(metaStrArr(md, "viewers"))
1936
- }),
1937
- pageId: PageId(pageId),
1938
- noindex: metaBool(md, "noindex")
1939
- };
1940
- }
1941
- }
2023
+ const md = route.metadata;
2024
+ const pageId = metaStr(md, "pageId");
2025
+ if (pageId == null) {
2026
+ return void 0;
1942
2027
  }
1943
- return void 0;
2028
+ const slug = ctx.contentSlug(route.fullPath);
2029
+ return {
2030
+ type: "landingPage",
2031
+ ...withMetadataDefaults({
2032
+ id: ctx.nodeId(`landing:${slug}`),
2033
+ title: metaStr(md, "title") ?? "",
2034
+ slug,
2035
+ icon: metaStr(md, "icon"),
2036
+ hidden: route.hidden,
2037
+ authed: metaBool(md, "authed"),
2038
+ viewers: toViewers(metaStrArr(md, "viewers")),
2039
+ orphaned: metaBool(md, "orphaned"),
2040
+ featureFlags: metaFeatureFlags(md)
2041
+ }),
2042
+ pageId: PageId(pageId),
2043
+ noindex: metaBool(md, "noindex")
2044
+ };
2045
+ }
2046
+ function buildLandingPage(ctx, scopeSegs) {
2047
+ const landingSegment = scopeSegs.find(
2048
+ (s) => metaStr(s.seg.metadata, "type") === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true
2049
+ );
2050
+ return routeToLandingPage(
2051
+ ctx,
2052
+ landingSegment?.nav.find((route) => route.type === "markdown")
2053
+ );
1944
2054
  }
1945
2055
  function markCrossVersionCanonicalSlugs(versionNodes) {
1946
2056
  const keyToCanonical = /* @__PURE__ */ new Map();
@@ -2000,7 +2110,7 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
2000
2110
  // here; sourcing it from the hash makes that filter match nothing.
2001
2111
  productId: ProductId(product.displayName),
2002
2112
  subtitle: metaStr(product.metadata, "subtitle") ?? "",
2003
- image: void 0,
2113
+ image: metaStr(product.metadata, "image") != null ? FileId(metaStr(product.metadata, "image")) : void 0,
2004
2114
  announcement: void 0,
2005
2115
  pointsTo: metaStr(product.metadata, "pointsTo") != null ? pointsToSlug(metaStr(product.metadata, "pointsTo")) : void 0,
2006
2116
  child: productChild
@@ -2011,7 +2121,10 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
2011
2121
  type: "productgroup",
2012
2122
  id: ctx.nodeId("productgroup"),
2013
2123
  collapsed: void 0,
2014
- landingPage: void 0,
2124
+ landingPage: buildLandingPage(
2125
+ ctx,
2126
+ scoped.filter((s) => s.seg.product == null)
2127
+ ),
2015
2128
  children
2016
2129
  };
2017
2130
  }