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

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.
@@ -1123,6 +1123,63 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
1123
1123
  }
1124
1124
  return void 0;
1125
1125
  }
1126
+ function apiLeafPositionKey(node) {
1127
+ switch (node.type) {
1128
+ case "endpoint":
1129
+ return `endpoint:${node.endpointId}`;
1130
+ case "webhook":
1131
+ return `webhook:${node.webhookId}`;
1132
+ case "webSocket":
1133
+ return `webSocket:${node.webSocketId}`;
1134
+ case "grpc":
1135
+ return `grpc:${node.grpcId}`;
1136
+ case "graphql":
1137
+ return `graphql:${node.graphqlOperationId}`;
1138
+ }
1139
+ }
1140
+ function apiChildPositionKey(node) {
1141
+ switch (node.type) {
1142
+ case "endpoint":
1143
+ case "webhook":
1144
+ case "webSocket":
1145
+ case "grpc":
1146
+ case "graphql":
1147
+ return apiLeafPositionKey(node);
1148
+ default:
1149
+ return void 0;
1150
+ }
1151
+ }
1152
+ function positionedApiLeafChildren(ctx, nav, apiDefinitionId) {
1153
+ const rawLeafNodes = [];
1154
+ const leafPositions = /* @__PURE__ */ new Map();
1155
+ const nonApiLeafNodes = [];
1156
+ for (let i = 0; i < nav.length; i++) {
1157
+ const route = nav[i];
1158
+ const pos = route.displaySortOrder ?? i;
1159
+ const apiLeaf = apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId);
1160
+ if (apiLeaf != null) {
1161
+ rawLeafNodes.push(apiLeaf);
1162
+ const key = apiLeafPositionKey(apiLeaf);
1163
+ leafPositions.set(key, Math.min(leafPositions.get(key) ?? pos, pos));
1164
+ continue;
1165
+ }
1166
+ const node = artifactToNode(ctx, route);
1167
+ if (node?.type === "page" || node?.type === "link") {
1168
+ nonApiLeafNodes.push({ node, pos });
1169
+ }
1170
+ }
1171
+ const apiLeafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
1172
+ const positionedApiLeafNodes = apiLeafNodes.map((node, index) => {
1173
+ if (node.type === "endpointPair") {
1174
+ const streamPos = leafPositions.get(apiLeafPositionKey(node.stream)) ?? index;
1175
+ const nonStreamPos = leafPositions.get(apiLeafPositionKey(node.nonStream)) ?? index;
1176
+ return { node, pos: Math.min(streamPos, nonStreamPos) };
1177
+ }
1178
+ const key = apiChildPositionKey(node);
1179
+ return { node, pos: key != null ? leafPositions.get(key) ?? index : index };
1180
+ });
1181
+ return [...positionedApiLeafNodes, ...nonApiLeafNodes];
1182
+ }
1126
1183
  function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefinitionId2) {
1127
1184
  const ctx = createBuildContext(basePath);
1128
1185
  return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2)).filter((node) => node != null);
@@ -1232,7 +1289,9 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1232
1289
  return {
1233
1290
  type: "section",
1234
1291
  ...defaults,
1235
- collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1292
+ // V2 convention: collapsed:false in docs.yml maps to "open-by-default"
1293
+ // so getInitiallyOpenByDefaultNodes picks it up and the UI starts open.
1294
+ collapsed: metaCollapsed(seg.metadata) === false ? "open-by-default" : metaCollapsed(seg.metadata) ?? defaults.collapsed,
1236
1295
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1237
1296
  noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1238
1297
  collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
@@ -1260,8 +1319,7 @@ function directChildApiPackages(parentSection, scopeSegs) {
1260
1319
  }
1261
1320
  function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix) {
1262
1321
  const { seg, nav } = scoped;
1263
- const rawLeafNodes = nav.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId)).filter((node) => node != null);
1264
- const leafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
1322
+ const leafNodes = positionedApiLeafChildren(ctx, nav, apiDefinitionId);
1265
1323
  const childPackages = directChildApiPackages(seg.section, scopeSegs);
1266
1324
  const packageNodes = childPackages.map((child) => ({
1267
1325
  node: apiPackageChildNode(
@@ -1275,18 +1333,10 @@ function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix)
1275
1333
  }));
1276
1334
  const hasChildIndex = packageNodes.some((p) => p.childIndex != null);
1277
1335
  if (!hasChildIndex) {
1278
- return [...leafNodes, ...packageNodes.map((p) => p.node)];
1279
- }
1280
- const leafPositions = [];
1281
- for (const route of nav) {
1282
- if (route.displaySortOrder != null) {
1283
- leafPositions.push(route.displaySortOrder);
1284
- }
1336
+ return [...leafNodes, ...packageNodes.map((p) => ({ node: p.node, pos: Number.MAX_SAFE_INTEGER }))].sort((a, b) => a.pos - b.pos).map((p) => p.node);
1285
1337
  }
1286
1338
  const positioned = [];
1287
- for (let i = 0; i < leafNodes.length; i++) {
1288
- positioned.push({ node: leafNodes[i], pos: leafPositions[i] ?? i });
1289
- }
1339
+ positioned.push(...leafNodes);
1290
1340
  for (const p of packageNodes) {
1291
1341
  positioned.push({ node: p.node, pos: p.childIndex ?? Number.MAX_SAFE_INTEGER });
1292
1342
  }
@@ -1707,6 +1757,24 @@ function buildFullRootFromSegments(options) {
1707
1757
  } else if (child.type === "versioned") {
1708
1758
  const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
1709
1759
  rootPointsTo = defaultVersion?.pointsTo;
1760
+ } else if (child.type === "unversioned") {
1761
+ if (tabs.length > 0) {
1762
+ const firstTab = tabs[0];
1763
+ const pt = firstTab != null ? metaStr(firstTab.metadata, "pointsTo") : void 0;
1764
+ rootPointsTo = pt != null ? pointsToSlug(pt) : void 0;
1765
+ } else {
1766
+ const sorted = [...scoped].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1767
+ for (const s of sorted) {
1768
+ if (s.seg.hidden) {
1769
+ continue;
1770
+ }
1771
+ const pt = metaStr(s.seg.metadata, "pointsTo");
1772
+ if (pt != null) {
1773
+ rootPointsTo = pointsToSlug(pt);
1774
+ break;
1775
+ }
1776
+ }
1777
+ }
1710
1778
  }
1711
1779
  const root = {
1712
1780
  type: "root",
@@ -1719,21 +1787,22 @@ function buildFullRootFromSegments(options) {
1719
1787
  return root;
1720
1788
  }
1721
1789
  function uniqueDetails(scoped, dim) {
1722
- const bySlug = /* @__PURE__ */ new Map();
1790
+ const byKey = /* @__PURE__ */ new Map();
1723
1791
  for (const s of scoped) {
1724
1792
  const d = s.seg[dim];
1725
1793
  if (d == null) {
1726
1794
  continue;
1727
1795
  }
1728
1796
  const slug = detailSlug(d);
1729
- const existing = bySlug.get(slug);
1797
+ const key = dim === "tab" ? d.id : slug !== "" ? slug : d.id;
1798
+ const existing = byKey.get(key);
1730
1799
  if (existing == null) {
1731
- bySlug.set(slug, d);
1800
+ byKey.set(key, d);
1732
1801
  } else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
1733
- bySlug.set(slug, d);
1802
+ byKey.set(key, d);
1734
1803
  }
1735
1804
  }
1736
- return [...bySlug.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1805
+ return [...byKey.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1737
1806
  }
1738
1807
  function scopeSlugPrefix(rootSlug, ...details) {
1739
1808
  const parts = [rootSlug];