@fern-api/fdr-sdk 1.2.39-b6eaa342cf → 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 (30) 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 +151 -43
  10. package/dist/js/navigation/ledger-root-builder.js.map +1 -1
  11. package/dist/js/navigation/ledger-root-builder.mjs +151 -43
  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.landingPage.test.d.ts +2 -0
  19. package/dist/types/navigation/__test__/ledger-root-builder.landingPage.test.d.ts.map +1 -0
  20. package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.test.d.ts +2 -0
  21. package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.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/ledger-root-builder.d.ts +12 -0
  25. package/dist/types/navigation/ledger-root-builder.d.ts.map +1 -1
  26. package/dist/types/orpc-client/docs-ledger/contract.d.ts +50 -0
  27. package/dist/types/orpc-client/docs-ledger/contract.d.ts.map +1 -1
  28. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts +12 -0
  29. package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts.map +1 -1
  30. package/package.json +3 -3
@@ -1248,12 +1248,10 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1248
1248
  return {
1249
1249
  type: "section",
1250
1250
  ...defaults,
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,
1251
+ collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1254
1252
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1255
1253
  noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1256
- 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),
1257
1255
  collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1258
1256
  availability: metaStr(seg.metadata, "availability"),
1259
1257
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
@@ -1480,7 +1478,7 @@ function changelogNode(ctx, scoped, scopePrefix) {
1480
1478
  pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
1481
1479
  noindex: metaBool(r.metadata, "noindex"),
1482
1480
  date: dateStr ?? "",
1483
- tags: void 0
1481
+ tags: metaStrArr(r.metadata, "tags")
1484
1482
  };
1485
1483
  let months = byYear.get(year);
1486
1484
  if (months == null) {
@@ -1587,17 +1585,55 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
1587
1585
  return { node, childIndex };
1588
1586
  });
1589
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
+ }
1590
1622
  function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1591
1623
  const ordered = [...scopeSegs].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1592
1624
  const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1593
1625
  const annotated = [];
1594
1626
  const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" && s.seg.section === "");
1627
+ const siblingBoundaries = computeSiblingSortBoundaries(ordered);
1595
1628
  for (const s of ordered) {
1596
1629
  const type = metaStr(s.seg.metadata, "type");
1597
1630
  const sec = s.seg.section;
1598
1631
  if (hasOwningApiReference(s, scopeSegs)) {
1599
1632
  continue;
1600
1633
  }
1634
+ if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
1635
+ continue;
1636
+ }
1601
1637
  if (type === "tabRoot" || sec === "" && type !== "section") {
1602
1638
  for (const r of s.nav) {
1603
1639
  const node = artifactToNode(ctx, r);
@@ -1625,14 +1661,21 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
1625
1661
  } else if (type === "changelog") {
1626
1662
  node = changelogNode(ctx, s, changelogScopePrefix ?? scopePrefix);
1627
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;
1628
1666
  node = sectionNode(
1629
1667
  ctx,
1630
1668
  s,
1631
- buildSectionTree(ctx, scopeSegs, sec, scopePrefix, changelogScopePrefix),
1669
+ buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix),
1632
1670
  scopePrefix
1633
1671
  );
1634
1672
  }
1635
- 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
+ });
1636
1679
  }
1637
1680
  }
1638
1681
  const hasLeafPos = annotated.some((a) => a.isLeaf && a.pos != null);
@@ -1684,13 +1727,13 @@ function buildSidebarRoot(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1684
1727
  };
1685
1728
  }
1686
1729
  function buildFullRootFromSegments(options) {
1687
- const { basePath, title, segments, navBySegment } = options;
1730
+ const { basePath, rootSlug: sourceRootSlug, title, segments, navBySegment, skipSharedSectionMerge } = options;
1688
1731
  const ctx = createBuildContext(basePath);
1689
1732
  const scoped = segments.filter((seg) => {
1690
1733
  const t = metaStr(seg.metadata, "type");
1691
1734
  return t !== "files" && t !== "redirects";
1692
1735
  }).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
1693
- const rootSlug = asSlug(basePath);
1736
+ const rootSlug = asSlug(sourceRootSlug ?? basePath);
1694
1737
  const scopesByKey = /* @__PURE__ */ new Map();
1695
1738
  for (const s of scoped) {
1696
1739
  const key = scopeKey(s.seg);
@@ -1703,9 +1746,9 @@ function buildFullRootFromSegments(options) {
1703
1746
  const tabs = uniqueDetails(scoped, "tab");
1704
1747
  let child;
1705
1748
  if (products.length > 0) {
1706
- child = buildProductGroup(ctx, products, scoped, rootSlug);
1749
+ child = buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge);
1707
1750
  } else if (versions.length > 0) {
1708
- child = buildVersioned(ctx, versions, scoped, rootSlug, void 0);
1751
+ child = buildVersioned(ctx, versions, scoped, rootSlug, void 0, skipSharedSectionMerge);
1709
1752
  } else {
1710
1753
  child = buildUnversioned(ctx, scoped, rootSlug, tabs.length > 0);
1711
1754
  }
@@ -1905,16 +1948,71 @@ function buildUnversioned(ctx, scopeSegs, scopePrefix, tabsPresent) {
1905
1948
  type: "unversioned",
1906
1949
  id: ctx.nodeId(`unversioned:${first?.seg.product?.id ?? "root"}`),
1907
1950
  collapsed: void 0,
1908
- landingPage: void 0,
1951
+ landingPage: buildLandingPage(ctx, scopeSegs),
1909
1952
  // The enclosing scope prefix (product slug, or rootSlug at the top
1910
1953
  // level) roots structural sections so they share the scope's slug
1911
1954
  // namespace.
1912
1955
  child: buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix)
1913
1956
  };
1914
1957
  }
1915
- 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 !== "");
1916
2011
  const children = versions.map((version) => {
1917
- 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
+ }
1918
2016
  const tabsPresent = uniqueDetails(versionSegs, "tab").length > 0;
1919
2017
  const prefix = productPrefix != null ? productPrefix : rootSlug;
1920
2018
  const versionSegment = detailSlug(version);
@@ -1932,7 +2030,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1932
2030
  default: detailIsDefault(version),
1933
2031
  versionId: VersionId(version.id),
1934
2032
  availability: void 0,
1935
- landingPage: buildVersionLandingPage(ctx, versionSegs, asSlug(slug)),
2033
+ landingPage: buildLandingPage(ctx, versionSegs),
1936
2034
  announcement: void 0,
1937
2035
  pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1938
2036
  // The version's full slug roots structural sections so the whole
@@ -2013,34 +2111,41 @@ function crossVersionDedupKeys(node, parents) {
2013
2111
  keys.push([...parentTitles, node.title].join("###"));
2014
2112
  return keys;
2015
2113
  }
2016
- function buildVersionLandingPage(ctx, versionSegs, versionSlug) {
2017
- const tablessSegs = versionSegs.filter((s) => s.seg.tab == null);
2018
- if (tablessSegs.length === 0) {
2114
+ function routeToLandingPage(ctx, route) {
2115
+ if (route == null || route.type !== "markdown" || route.fullPath == null) {
2019
2116
  return void 0;
2020
2117
  }
2021
- for (const s of tablessSegs) {
2022
- for (const r of s.nav) {
2023
- if (r.type === "markdown" && r.fullPath != null) {
2024
- const md = r.metadata;
2025
- const pageId = metaStr(md, "pageId") ?? "";
2026
- const slug = ctx.contentSlug(r.fullPath);
2027
- return {
2028
- type: "landingPage",
2029
- ...withMetadataDefaults({
2030
- id: ctx.nodeId(`landing:${slug}`),
2031
- title: metaStr(md, "title") ?? "",
2032
- slug,
2033
- icon: metaStr(md, "icon"),
2034
- hidden: r.hidden,
2035
- viewers: toViewers(metaStrArr(md, "viewers"))
2036
- }),
2037
- pageId: PageId(pageId),
2038
- noindex: metaBool(md, "noindex")
2039
- };
2040
- }
2041
- }
2118
+ const md = route.metadata;
2119
+ const pageId = metaStr(md, "pageId");
2120
+ if (pageId == null) {
2121
+ return void 0;
2042
2122
  }
2043
- 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
+ );
2044
2149
  }
2045
2150
  function markCrossVersionCanonicalSlugs(versionNodes) {
2046
2151
  const keyToCanonical = /* @__PURE__ */ new Map();
@@ -2075,13 +2180,13 @@ function markCrossVersionCanonicalSlugs(versionNodes) {
2075
2180
  });
2076
2181
  }
2077
2182
  }
2078
- function buildProductGroup(ctx, products, scoped, rootSlug) {
2183
+ function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge) {
2079
2184
  const children = products.map((product) => {
2080
2185
  const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
2081
2186
  const versions = uniqueDetails(productSegs, "version");
2082
2187
  const tabsPresent = uniqueDetails(productSegs, "tab").length > 0;
2083
2188
  const productPrefix = scopeSlugPrefix(rootSlug, product);
2084
- 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);
2085
2190
  const node = {
2086
2191
  type: "product",
2087
2192
  ...withMetadataDefaults({
@@ -2111,7 +2216,10 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
2111
2216
  type: "productgroup",
2112
2217
  id: ctx.nodeId("productgroup"),
2113
2218
  collapsed: void 0,
2114
- landingPage: void 0,
2219
+ landingPage: buildLandingPage(
2220
+ ctx,
2221
+ scoped.filter((s) => s.seg.product == null)
2222
+ ),
2115
2223
  children
2116
2224
  };
2117
2225
  }