@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
@@ -1289,12 +1289,10 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
1289
1289
  return {
1290
1290
  type: "section",
1291
1291
  ...defaults,
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,
1292
+ collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
1295
1293
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1296
1294
  noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
1297
- collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
1295
+ collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1298
1296
  collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
1299
1297
  availability: metaStr(seg.metadata, "availability"),
1300
1298
  pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
@@ -1521,7 +1519,7 @@ function changelogNode(ctx, scoped, scopePrefix) {
1521
1519
  pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
1522
1520
  noindex: metaBool(r.metadata, "noindex"),
1523
1521
  date: dateStr ?? "",
1524
- tags: void 0
1522
+ tags: metaStrArr(r.metadata, "tags")
1525
1523
  };
1526
1524
  let months = byYear.get(year);
1527
1525
  if (months == null) {
@@ -1628,17 +1626,55 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
1628
1626
  return { node, childIndex };
1629
1627
  });
1630
1628
  }
1629
+ function computeSiblingSortBoundaries(ordered) {
1630
+ const result = /* @__PURE__ */ new Map();
1631
+ const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1632
+ const rootSections = [];
1633
+ for (const s of ordered) {
1634
+ const type = metaStr(s.seg.metadata, "type");
1635
+ const sec = s.seg.section;
1636
+ if (type !== "section" || sec === "") {
1637
+ continue;
1638
+ }
1639
+ const parent = parentSectionPath(sec);
1640
+ const isRootLevel = parent === "" || !sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "";
1641
+ if (isRootLevel) {
1642
+ rootSections.push(s);
1643
+ }
1644
+ }
1645
+ const byPath = /* @__PURE__ */ new Map();
1646
+ for (const s of rootSections) {
1647
+ const group = byPath.get(s.seg.section) ?? [];
1648
+ group.push(s);
1649
+ byPath.set(s.seg.section, group);
1650
+ }
1651
+ for (const [, siblings] of byPath) {
1652
+ if (siblings.length <= 1) {
1653
+ continue;
1654
+ }
1655
+ for (let i = 0; i < siblings.length; i++) {
1656
+ const lo = siblings[i].seg.sortOrder;
1657
+ const hi = i + 1 < siblings.length ? siblings[i + 1].seg.sortOrder : Number.MAX_SAFE_INTEGER;
1658
+ result.set(siblings[i], { lo, hi });
1659
+ }
1660
+ }
1661
+ return result;
1662
+ }
1631
1663
  function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1632
1664
  const ordered = [...scopeSegs].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1633
1665
  const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1634
1666
  const annotated = [];
1635
1667
  const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" && s.seg.section === "");
1668
+ const siblingBoundaries = computeSiblingSortBoundaries(ordered);
1636
1669
  for (const s of ordered) {
1637
1670
  const type = metaStr(s.seg.metadata, "type");
1638
1671
  const sec = s.seg.section;
1639
1672
  if (hasOwningApiReference(s, scopeSegs)) {
1640
1673
  continue;
1641
1674
  }
1675
+ if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
1676
+ continue;
1677
+ }
1642
1678
  if (type === "tabRoot" || sec === "" && type !== "section") {
1643
1679
  for (const r of s.nav) {
1644
1680
  const node = artifactToNode(ctx, r);
@@ -1666,14 +1702,21 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
1666
1702
  } else if (type === "changelog") {
1667
1703
  node = changelogNode(ctx, s, changelogScopePrefix ?? scopePrefix);
1668
1704
  } else {
1705
+ const bounds = siblingBoundaries.get(s);
1706
+ const ownedSegs = bounds != null ? scopeSegs.filter((seg) => seg.seg.sortOrder >= bounds.lo && seg.seg.sortOrder < bounds.hi) : scopeSegs;
1669
1707
  node = sectionNode(
1670
1708
  ctx,
1671
1709
  s,
1672
- buildSectionTree(ctx, scopeSegs, sec, scopePrefix, changelogScopePrefix),
1710
+ buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix),
1673
1711
  scopePrefix
1674
1712
  );
1675
1713
  }
1676
- annotated.push({ node, pos: metaNum(s.seg.metadata, "childIndex"), isLeaf: false });
1714
+ const isSharedSection = siblingBoundaries.size > 0 && scopePrefix !== "" && sec !== "" && !sec.startsWith(scopePrefix);
1715
+ annotated.push({
1716
+ node,
1717
+ pos: isSharedSection ? void 0 : metaNum(s.seg.metadata, "childIndex"),
1718
+ isLeaf: false
1719
+ });
1677
1720
  }
1678
1721
  }
1679
1722
  const hasLeafPos = annotated.some((a) => a.isLeaf && a.pos != null);
@@ -1725,13 +1768,13 @@ function buildSidebarRoot(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
1725
1768
  };
1726
1769
  }
1727
1770
  function buildFullRootFromSegments(options) {
1728
- const { basePath, title, segments, navBySegment } = options;
1771
+ const { basePath, rootSlug: sourceRootSlug, title, segments, navBySegment, skipSharedSectionMerge } = options;
1729
1772
  const ctx = createBuildContext(basePath);
1730
1773
  const scoped = segments.filter((seg) => {
1731
1774
  const t = metaStr(seg.metadata, "type");
1732
1775
  return t !== "files" && t !== "redirects";
1733
1776
  }).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
1734
- const rootSlug = asSlug(basePath);
1777
+ const rootSlug = asSlug(sourceRootSlug ?? basePath);
1735
1778
  const scopesByKey = /* @__PURE__ */ new Map();
1736
1779
  for (const s of scoped) {
1737
1780
  const key = scopeKey(s.seg);
@@ -1744,9 +1787,9 @@ function buildFullRootFromSegments(options) {
1744
1787
  const tabs = uniqueDetails(scoped, "tab");
1745
1788
  let child;
1746
1789
  if (products.length > 0) {
1747
- child = buildProductGroup(ctx, products, scoped, rootSlug);
1790
+ child = buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge);
1748
1791
  } else if (versions.length > 0) {
1749
- child = buildVersioned(ctx, versions, scoped, rootSlug, void 0);
1792
+ child = buildVersioned(ctx, versions, scoped, rootSlug, void 0, skipSharedSectionMerge);
1750
1793
  } else {
1751
1794
  child = buildUnversioned(ctx, scoped, rootSlug, tabs.length > 0);
1752
1795
  }
@@ -1946,16 +1989,71 @@ function buildUnversioned(ctx, scopeSegs, scopePrefix, tabsPresent) {
1946
1989
  type: "unversioned",
1947
1990
  id: ctx.nodeId(`unversioned:${first?.seg.product?.id ?? "root"}`),
1948
1991
  collapsed: void 0,
1949
- landingPage: void 0,
1992
+ landingPage: buildLandingPage(ctx, scopeSegs),
1950
1993
  // The enclosing scope prefix (product slug, or rootSlug at the top
1951
1994
  // level) roots structural sections so they share the scope's slug
1952
1995
  // namespace.
1953
1996
  child: buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix)
1954
1997
  };
1955
1998
  }
1956
- function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1999
+ function mergeSharedSections(defaultSegs, allScoped, defaultVersion, versionSlugs) {
2000
+ const defaultTabsByName = /* @__PURE__ */ new Map();
2001
+ for (const s of defaultSegs) {
2002
+ if (s.seg.tab != null) {
2003
+ const tabName = s.seg.tab.displayName;
2004
+ if (!defaultTabsByName.has(tabName)) {
2005
+ defaultTabsByName.set(tabName, s.seg.tab);
2006
+ }
2007
+ }
2008
+ }
2009
+ const existingSections = new Set(
2010
+ defaultSegs.filter((s) => metaStr(s.seg.metadata, "type") === "section").map((s) => s.seg.section)
2011
+ );
2012
+ const maxSortOrder = defaultSegs.reduce((max, s) => Math.max(max, s.seg.sortOrder), 0);
2013
+ let nextSortOrder = maxSortOrder + 1;
2014
+ const merged = [...defaultSegs];
2015
+ for (const s of allScoped) {
2016
+ if (s.seg.version?.id === defaultVersion.id) {
2017
+ continue;
2018
+ }
2019
+ const type = metaStr(s.seg.metadata, "type");
2020
+ if (type !== "section") {
2021
+ continue;
2022
+ }
2023
+ const sectionPath = s.seg.section;
2024
+ if (versionSlugs.some((vs) => sectionPath === vs || sectionPath.startsWith(vs + "/"))) {
2025
+ continue;
2026
+ }
2027
+ if (existingSections.has(sectionPath)) {
2028
+ continue;
2029
+ }
2030
+ const sourceTabName = s.seg.tab?.displayName ?? "";
2031
+ const targetTab = defaultTabsByName.get(sourceTabName);
2032
+ if (targetTab == null) {
2033
+ continue;
2034
+ }
2035
+ const metadata = s.seg.metadata != null ? { ...s.seg.metadata, childIndex: void 0 } : s.seg.metadata;
2036
+ merged.push({
2037
+ seg: {
2038
+ ...s.seg,
2039
+ tab: targetTab,
2040
+ version: defaultVersion,
2041
+ sortOrder: nextSortOrder++,
2042
+ metadata
2043
+ },
2044
+ nav: s.nav
2045
+ });
2046
+ existingSections.add(sectionPath);
2047
+ }
2048
+ return merged;
2049
+ }
2050
+ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix, skipSharedSectionMerge) {
2051
+ const versionSlugs = versions.map((v) => detailSlug(v)).filter((s) => s !== "");
1957
2052
  const children = versions.map((version) => {
1958
- const versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
2053
+ let versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
2054
+ if (detailIsDefault(version) && !skipSharedSectionMerge) {
2055
+ versionSegs = mergeSharedSections(versionSegs, scoped, version, versionSlugs);
2056
+ }
1959
2057
  const tabsPresent = uniqueDetails(versionSegs, "tab").length > 0;
1960
2058
  const prefix = productPrefix != null ? productPrefix : rootSlug;
1961
2059
  const versionSegment = detailSlug(version);
@@ -1973,7 +2071,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1973
2071
  default: detailIsDefault(version),
1974
2072
  versionId: VersionId(version.id),
1975
2073
  availability: void 0,
1976
- landingPage: buildVersionLandingPage(ctx, versionSegs, asSlug(slug)),
2074
+ landingPage: buildLandingPage(ctx, versionSegs),
1977
2075
  announcement: void 0,
1978
2076
  pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1979
2077
  // The version's full slug roots structural sections so the whole
@@ -2054,34 +2152,41 @@ function crossVersionDedupKeys(node, parents) {
2054
2152
  keys.push([...parentTitles, node.title].join("###"));
2055
2153
  return keys;
2056
2154
  }
2057
- function buildVersionLandingPage(ctx, versionSegs, versionSlug) {
2058
- const tablessSegs = versionSegs.filter((s) => s.seg.tab == null);
2059
- if (tablessSegs.length === 0) {
2155
+ function routeToLandingPage(ctx, route) {
2156
+ if (route == null || route.type !== "markdown" || route.fullPath == null) {
2060
2157
  return void 0;
2061
2158
  }
2062
- for (const s of tablessSegs) {
2063
- for (const r of s.nav) {
2064
- if (r.type === "markdown" && r.fullPath != null) {
2065
- const md = r.metadata;
2066
- const pageId = metaStr(md, "pageId") ?? "";
2067
- const slug = ctx.contentSlug(r.fullPath);
2068
- return {
2069
- type: "landingPage",
2070
- ...withMetadataDefaults({
2071
- id: ctx.nodeId(`landing:${slug}`),
2072
- title: metaStr(md, "title") ?? "",
2073
- slug,
2074
- icon: metaStr(md, "icon"),
2075
- hidden: r.hidden,
2076
- viewers: toViewers(metaStrArr(md, "viewers"))
2077
- }),
2078
- pageId: PageId(pageId),
2079
- noindex: metaBool(md, "noindex")
2080
- };
2081
- }
2082
- }
2159
+ const md = route.metadata;
2160
+ const pageId = metaStr(md, "pageId");
2161
+ if (pageId == null) {
2162
+ return void 0;
2083
2163
  }
2084
- return void 0;
2164
+ const slug = ctx.contentSlug(route.fullPath);
2165
+ return {
2166
+ type: "landingPage",
2167
+ ...withMetadataDefaults({
2168
+ id: ctx.nodeId(`landing:${slug}`),
2169
+ title: metaStr(md, "title") ?? "",
2170
+ slug,
2171
+ icon: metaStr(md, "icon"),
2172
+ hidden: route.hidden,
2173
+ authed: metaBool(md, "authed"),
2174
+ viewers: toViewers(metaStrArr(md, "viewers")),
2175
+ orphaned: metaBool(md, "orphaned"),
2176
+ featureFlags: metaFeatureFlags(md)
2177
+ }),
2178
+ pageId: PageId(pageId),
2179
+ noindex: metaBool(md, "noindex")
2180
+ };
2181
+ }
2182
+ function buildLandingPage(ctx, scopeSegs) {
2183
+ const landingSegment = scopeSegs.find(
2184
+ (s) => metaStr(s.seg.metadata, "type") === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true
2185
+ );
2186
+ return routeToLandingPage(
2187
+ ctx,
2188
+ landingSegment?.nav.find((route) => route.type === "markdown")
2189
+ );
2085
2190
  }
2086
2191
  function markCrossVersionCanonicalSlugs(versionNodes) {
2087
2192
  const keyToCanonical = /* @__PURE__ */ new Map();
@@ -2116,13 +2221,13 @@ function markCrossVersionCanonicalSlugs(versionNodes) {
2116
2221
  });
2117
2222
  }
2118
2223
  }
2119
- function buildProductGroup(ctx, products, scoped, rootSlug) {
2224
+ function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge) {
2120
2225
  const children = products.map((product) => {
2121
2226
  const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
2122
2227
  const versions = uniqueDetails(productSegs, "version");
2123
2228
  const tabsPresent = uniqueDetails(productSegs, "tab").length > 0;
2124
2229
  const productPrefix = scopeSlugPrefix(rootSlug, product);
2125
- const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
2230
+ const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix, skipSharedSectionMerge) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
2126
2231
  const node = {
2127
2232
  type: "product",
2128
2233
  ...withMetadataDefaults({
@@ -2152,7 +2257,10 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
2152
2257
  type: "productgroup",
2153
2258
  id: ctx.nodeId("productgroup"),
2154
2259
  collapsed: void 0,
2155
- landingPage: void 0,
2260
+ landingPage: buildLandingPage(
2261
+ ctx,
2262
+ scoped.filter((s) => s.seg.product == null)
2263
+ ),
2156
2264
  children
2157
2265
  };
2158
2266
  }