@fern-api/fdr-sdk 1.2.34-5c94d72077 → 1.2.35-07f6dfd14f

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.
@@ -612,6 +612,9 @@ function slugjoin(...parts) {
612
612
  }
613
613
 
614
614
  // src/navigation/ledger-root-builder.ts
615
+ var segMeta = (seg) => seg.metadata ?? {};
616
+ var routeMeta = (route) => route.metadata ?? {};
617
+ var detailMeta = (detail) => detail.metadata ?? {};
615
618
  function createBuildContext(basePath) {
616
619
  const seen = /* @__PURE__ */ new Map();
617
620
  const basePrefix = basePath.replace(/^\/+|\/+$/g, "");
@@ -630,41 +633,6 @@ function createBuildContext(basePath) {
630
633
  function asSlug(path) {
631
634
  return Slug(path.replace(/^\/+|\/+$/g, ""));
632
635
  }
633
- function metaStr(metadata, key) {
634
- if (metadata != null && typeof metadata === "object" && key in metadata) {
635
- const v = metadata[key];
636
- return typeof v === "string" ? v : void 0;
637
- }
638
- return void 0;
639
- }
640
- function metaBool(metadata, key) {
641
- if (metadata != null && typeof metadata === "object" && key in metadata) {
642
- const v = metadata[key];
643
- return typeof v === "boolean" ? v : void 0;
644
- }
645
- return void 0;
646
- }
647
- function metaCollapsed(metadata) {
648
- if (metadata != null && typeof metadata === "object" && "collapsed" in metadata) {
649
- const v = metadata.collapsed;
650
- if (typeof v === "boolean") {
651
- return v;
652
- }
653
- if (v === "open-by-default") {
654
- return "open-by-default";
655
- }
656
- }
657
- return void 0;
658
- }
659
- function metaStrArr(metadata, key) {
660
- if (metadata != null && typeof metadata === "object" && key in metadata) {
661
- const v = metadata[key];
662
- if (Array.isArray(v)) {
663
- return v.filter((x) => typeof x === "string");
664
- }
665
- }
666
- return void 0;
667
- }
668
636
  function toViewers(viewers) {
669
637
  if (viewers == null || viewers.length === 0) {
670
638
  return void 0;
@@ -672,29 +640,17 @@ function toViewers(viewers) {
672
640
  return viewers.map((v) => RoleId(v));
673
641
  }
674
642
  function mergeVariantViewers(seg) {
675
- const segViewers = metaStrArr(seg.metadata, "viewers");
676
- const variantViewers = seg.variant?.viewers;
677
- if ((segViewers == null || segViewers.length === 0) && (variantViewers == null || variantViewers.length === 0)) {
678
- return void 0;
679
- }
680
- const merged = /* @__PURE__ */ new Set();
681
- if (segViewers != null) {
682
- for (const v of segViewers) {
683
- merged.add(v);
684
- }
685
- }
686
- if (variantViewers != null) {
687
- for (const v of variantViewers) {
688
- merged.add(v);
689
- }
690
- }
691
- return merged.size > 0 ? [...merged].map((v) => RoleId(v)) : void 0;
643
+ const all = [...segMeta(seg).viewers ?? [], ...seg.variant?.viewers ?? []];
644
+ return all.length > 0 ? [...new Set(all)].map((v) => RoleId(v)) : void 0;
692
645
  }
693
646
  function detailSlug(detail) {
694
- return metaStr(detail.metadata, "slug") ?? "";
647
+ return detailMeta(detail).slug ?? "";
695
648
  }
696
649
  function detailIsDefault(detail) {
697
- return metaBool(detail.metadata, "default") ?? false;
650
+ return detailMeta(detail).default ?? false;
651
+ }
652
+ function pointsToSlug(ctx, meta) {
653
+ return meta.pointsTo != null ? ctx.contentSlug(meta.pointsTo) : void 0;
698
654
  }
699
655
  function scopeKey(seg) {
700
656
  return [seg.product?.id ?? "", seg.version?.id ?? "", seg.variant?.id ?? "", seg.tab?.id ?? ""].join("|");
@@ -714,240 +670,223 @@ function withMetadataDefaults(base) {
714
670
  };
715
671
  }
716
672
  function artifactToNode(ctx, route) {
717
- const md = route.metadata;
718
- const title = metaStr(md, "title") ?? "";
719
- const icon = metaStr(md, "icon");
720
- const viewers = toViewers(metaStrArr(md, "viewers"));
673
+ const md = routeMeta(route);
721
674
  const slug = ctx.contentSlug(route.fullPath ?? "");
722
675
  switch (route.type) {
723
676
  case "markdown": {
724
- if (metaBool(md, "isOverview")) {
677
+ if (md.isOverview) {
725
678
  return void 0;
726
679
  }
727
- const pageId = metaStr(md, "pageId") ?? "";
728
- const node = {
680
+ return {
729
681
  type: "page",
730
682
  ...withMetadataDefaults({
731
683
  id: ctx.nodeId(`page:${slug}`),
732
- title,
684
+ title: md.title ?? "",
733
685
  slug,
734
- icon,
686
+ icon: md.icon,
735
687
  hidden: route.hidden,
736
- viewers
688
+ viewers: toViewers(md.viewers)
737
689
  }),
738
- pageId: PageId(pageId),
739
- noindex: metaBool(md, "noindex"),
690
+ pageId: PageId(md.pageId ?? ""),
691
+ noindex: md.noindex,
740
692
  availability: void 0
741
693
  };
742
- return node;
743
694
  }
744
695
  case "link": {
745
- const node = {
696
+ return {
746
697
  type: "link",
747
- id: ctx.nodeId(`link:${metaStr(md, "url") ?? route.fullPath ?? ""}`),
698
+ id: ctx.nodeId(`link:${md.url ?? route.fullPath ?? ""}`),
748
699
  collapsed: void 0,
749
- title,
750
- icon,
751
- url: Url(metaStr(md, "url") ?? ""),
700
+ title: md.title ?? "",
701
+ icon: md.icon,
702
+ url: Url(md.url ?? ""),
752
703
  target: void 0
753
704
  };
754
- return node;
755
705
  }
756
706
  // API leaf types are handled by apiReferenceNode (which calls
757
707
  // apiLeafNodeFromNavRouteInternal), not by section-level artifact
758
708
  // conversion. Returning undefined here prevents them from appearing
759
709
  // as duplicate siblings alongside the apiReference node.
760
- case "rest":
761
- case "asyncapi":
762
- case "webhook":
763
- case "grpc":
764
- case "graphql":
765
- return void 0;
766
710
  default:
767
711
  return void 0;
768
712
  }
769
713
  }
770
- function apiLeafNodeFromNavRoute(route, basePath, segmentApiDefinitionId2) {
714
+ function apiLeafNodeFromNavRoute(route, basePath, segmentApiDefId) {
771
715
  const ctx = createBuildContext(basePath);
772
- return apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2);
716
+ return apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefId);
773
717
  }
774
- function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
775
- const md = route.metadata;
776
- const apiDefinitionId = ApiDefinitionId(metaStr(md, "apiDefinitionId") ?? segmentApiDefinitionId2);
718
+ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefId) {
719
+ const md = routeMeta(route);
777
720
  const slug = ctx.contentSlug(route.fullPath ?? "");
778
- const title = metaStr(md, "title") ?? "";
779
- const icon = metaStr(md, "icon");
780
- const viewers = toViewers(metaStrArr(md, "viewers"));
781
- const meta = withMetadataDefaults({
782
- id: ctx.nodeId(`api-leaf:${slug}`),
783
- title,
784
- slug,
785
- icon,
786
- hidden: route.hidden,
787
- viewers
788
- });
789
- if (route.type === "rest") {
790
- const endpointId = metaStr(md, "endpointId");
791
- const method = metaStr(md, "method");
792
- if (endpointId == null || method == null) {
793
- return void 0;
794
- }
795
- return {
796
- type: "endpoint",
797
- ...meta,
798
- method,
799
- endpointId: EndpointId(endpointId),
800
- apiDefinitionId,
801
- isResponseStream: metaBool(md, "isResponseStream"),
802
- availability: void 0,
803
- playground: void 0
804
- };
805
- }
806
- if (route.type === "webhook") {
807
- const webhookId = metaStr(md, "webhookId");
808
- const method = metaStr(md, "method");
809
- if (webhookId == null || method == null) {
810
- return void 0;
811
- }
812
- return {
813
- type: "webhook",
814
- ...meta,
815
- method,
816
- webhookId: WebhookId(webhookId),
817
- apiDefinitionId,
818
- availability: void 0
819
- };
820
- }
821
- if (route.type === "asyncapi") {
822
- const webSocketId = metaStr(md, "webSocketId");
823
- if (webSocketId == null) {
824
- return void 0;
825
- }
826
- return {
827
- type: "webSocket",
828
- ...meta,
829
- webSocketId: WebSocketId(webSocketId),
830
- apiDefinitionId,
831
- availability: void 0,
832
- playground: void 0
833
- };
834
- }
835
- if (route.type === "grpc") {
836
- const grpcId = metaStr(md, "grpcId");
837
- const method = metaStr(md, "method");
838
- if (grpcId == null || method == null) {
839
- return void 0;
840
- }
841
- return {
842
- type: "grpc",
843
- ...meta,
844
- method,
845
- grpcId: GrpcId(grpcId),
846
- apiDefinitionId,
847
- availability: void 0
848
- };
849
- }
850
- if (route.type === "graphql") {
851
- const graphqlOperationId = metaStr(md, "graphqlOperationId");
852
- const operationType = metaStr(md, "operationType");
853
- if (graphqlOperationId == null || operationType == null) {
721
+ const base = {
722
+ ...withMetadataDefaults({
723
+ id: ctx.nodeId(`api-leaf:${slug}`),
724
+ title: md.title ?? "",
725
+ slug,
726
+ icon: md.icon,
727
+ hidden: route.hidden,
728
+ viewers: toViewers(md.viewers)
729
+ }),
730
+ apiDefinitionId: ApiDefinitionId(md.apiDefinitionId ?? segmentApiDefId),
731
+ availability: void 0
732
+ };
733
+ switch (route.type) {
734
+ case "rest":
735
+ if (md.endpointId == null || md.method == null) {
736
+ return void 0;
737
+ }
738
+ return {
739
+ type: "endpoint",
740
+ ...base,
741
+ method: md.method,
742
+ endpointId: EndpointId(md.endpointId),
743
+ isResponseStream: md.isResponseStream,
744
+ playground: void 0
745
+ };
746
+ case "webhook":
747
+ if (md.webhookId == null || md.method == null) {
748
+ return void 0;
749
+ }
750
+ return {
751
+ type: "webhook",
752
+ ...base,
753
+ method: md.method,
754
+ webhookId: WebhookId(md.webhookId)
755
+ };
756
+ case "asyncapi":
757
+ if (md.webSocketId == null) {
758
+ return void 0;
759
+ }
760
+ return {
761
+ type: "webSocket",
762
+ ...base,
763
+ webSocketId: WebSocketId(md.webSocketId),
764
+ playground: void 0
765
+ };
766
+ case "grpc":
767
+ if (md.grpcId == null || md.method == null) {
768
+ return void 0;
769
+ }
770
+ return {
771
+ type: "grpc",
772
+ ...base,
773
+ method: md.method,
774
+ grpcId: GrpcId(md.grpcId)
775
+ };
776
+ case "graphql":
777
+ if (md.graphqlOperationId == null || md.operationType == null) {
778
+ return void 0;
779
+ }
780
+ return {
781
+ type: "graphql",
782
+ ...base,
783
+ operationType: md.operationType,
784
+ graphqlOperationId: GraphQlOperationId(md.graphqlOperationId),
785
+ graphqlOperationIds: void 0,
786
+ playground: void 0
787
+ };
788
+ default:
854
789
  return void 0;
855
- }
856
- return {
857
- type: "graphql",
858
- ...meta,
859
- operationType,
860
- graphqlOperationId: GraphQlOperationId(graphqlOperationId),
861
- graphqlOperationIds: void 0,
862
- apiDefinitionId,
863
- availability: void 0,
864
- playground: void 0
865
- };
866
790
  }
867
- return void 0;
868
791
  }
869
- function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefinitionId2) {
792
+ function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefId) {
870
793
  const ctx = createBuildContext(basePath);
871
- return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2)).filter((node) => node != null);
794
+ return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefId)).filter((node) => node != null);
872
795
  }
873
796
  function segmentApiDefinitionId(metadata) {
874
- return metaStr(metadata, "apiDefinitionId");
797
+ return metadata?.apiDefinitionId;
875
798
  }
876
799
  function overviewRoute(nav) {
877
- return nav.find((r) => r.type === "markdown" && metaBool(r.metadata, "isOverview"));
800
+ for (const r of nav) {
801
+ if (r.type === "markdown") {
802
+ const meta = routeMeta(r);
803
+ if (meta.isOverview) {
804
+ return { route: r, meta };
805
+ }
806
+ }
807
+ }
808
+ return void 0;
878
809
  }
879
810
  function sectionNode(ctx, scoped, sectionChildren) {
880
- const { seg, nav } = scoped;
811
+ const { seg, meta: sm, nav } = scoped;
881
812
  const overview = overviewRoute(nav);
882
- const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
883
- const slug = ctx.contentSlug(overview?.fullPath ?? seg.section);
813
+ const overviewPageId = overview?.meta.pageId;
814
+ const slug = ctx.contentSlug(overview?.route.fullPath ?? seg.section);
884
815
  const leafChildren = nav.map((r) => artifactToNode(ctx, r)).filter((n) => n != null);
885
816
  const defaults = withMetadataDefaults({
886
817
  id: ctx.nodeId(`section:${slug}`),
887
- title: metaStr(seg.metadata, "title") ?? "",
818
+ title: sm.title ?? "",
888
819
  slug,
889
- icon: metaStr(seg.metadata, "icon"),
820
+ icon: sm.icon,
890
821
  hidden: seg.hidden,
891
822
  viewers: mergeVariantViewers(seg)
892
823
  });
893
824
  return {
894
825
  type: "section",
895
826
  ...defaults,
896
- collapsed: metaCollapsed(seg.metadata) ?? defaults.collapsed,
827
+ collapsed: sm.collapsed ?? defaults.collapsed,
897
828
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
898
829
  noindex: void 0,
899
- collapsible: metaBool(seg.metadata, "collapsible"),
900
- collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault"),
830
+ collapsible: sm.collapsible,
831
+ collapsedByDefault: sm.collapsedByDefault,
901
832
  availability: void 0,
902
833
  pointsTo: void 0,
903
834
  children: [...leafChildren, ...sectionChildren]
904
835
  };
905
836
  }
906
- function directChildApiPackages(parentSection, scopeSegs) {
907
- const sectionPaths = new Set(scopeSegs.map((s) => s.seg.section));
908
- return scopeSegs.filter((s) => {
909
- if (metaStr(s.seg.metadata, "type") !== "apiPackage") {
910
- return false;
911
- }
912
- const parent = parentSectionPath(s.seg.section);
913
- if (parent === parentSection) {
914
- return true;
915
- }
916
- if (!sectionPaths.has(parent)) {
917
- return nearestExistingAncestor(s.seg.section, sectionPaths) === parentSection;
837
+ function parentSectionPath(sectionPath) {
838
+ const idx = sectionPath.lastIndexOf("/");
839
+ return idx === -1 ? "" : sectionPath.slice(0, idx);
840
+ }
841
+ function nearestExistingAncestor(sectionPath, existing) {
842
+ let current = parentSectionPath(sectionPath);
843
+ while (current !== "") {
844
+ if (existing.has(current)) {
845
+ return current;
918
846
  }
919
- return false;
920
- }).sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
847
+ current = parentSectionPath(current);
848
+ }
849
+ return "";
850
+ }
851
+ function isDirectChildOf(sec, parentPath, sectionPaths) {
852
+ const parent = parentSectionPath(sec);
853
+ if (parent === parentPath) {
854
+ return true;
855
+ }
856
+ return !sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === parentPath;
921
857
  }
922
- function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId) {
923
- const { seg, nav } = scoped;
924
- const rawLeafNodes = nav.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, apiDefinitionId)).filter((node) => node != null);
858
+ function directChildApiPackages(parentSection, scopeSegs, sectionPaths) {
859
+ return scopeSegs.filter((s) => s.meta.type === "apiPackage" && isDirectChildOf(s.seg.section, parentSection, sectionPaths)).sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
860
+ }
861
+ function buildApiChildren(ctx, scoped, scopeSegs, apiDefId, sectionPaths) {
862
+ const { nav } = scoped;
863
+ const rawLeafNodes = nav.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, apiDefId)).filter((node) => node != null);
925
864
  const leafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
926
- const childPackages = directChildApiPackages(seg.section, scopeSegs);
865
+ const childPackages = directChildApiPackages(scoped.seg.section, scopeSegs, sectionPaths);
927
866
  const packageNodes = childPackages.map(
928
- (child) => apiPackageChildNode(ctx, child, scopeSegs, apiDefinitionId)
867
+ (child) => apiPackageChildNode(ctx, child, scopeSegs, apiDefId, sectionPaths)
929
868
  );
930
869
  return [...leafNodes, ...packageNodes];
931
870
  }
932
- function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId) {
933
- const { seg, nav } = scoped;
871
+ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefId, sectionPaths) {
872
+ const { seg, meta: sm, nav } = scoped;
934
873
  const overview = overviewRoute(nav);
935
- const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
936
- const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? parentApiDefinitionId;
937
- const slug = ctx.contentSlug(overview?.fullPath ?? nav[0]?.fullPath ?? seg.section);
938
- const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId);
874
+ const overviewPageId = overview?.meta.pageId;
875
+ const apiDefId = sm.apiDefinitionId ?? parentApiDefId;
876
+ const slug = ctx.contentSlug(overview?.route.fullPath ?? nav[0]?.fullPath ?? seg.section);
877
+ const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefId, sectionPaths);
939
878
  return {
940
879
  type: "apiPackage",
941
880
  ...withMetadataDefaults({
942
881
  id: ctx.nodeId(`api-pkg:${slug}`),
943
- title: metaStr(seg.metadata, "title") ?? "",
882
+ title: sm.title ?? "",
944
883
  slug,
945
- icon: metaStr(seg.metadata, "icon"),
884
+ icon: sm.icon,
946
885
  hidden: seg.hidden,
947
- viewers: toViewers(metaStrArr(seg.metadata, "viewers"))
886
+ viewers: toViewers(sm.viewers)
948
887
  }),
949
- apiDefinitionId: ApiDefinitionId(apiDefinitionId),
950
- availability: metaStr(seg.metadata, "availability"),
888
+ apiDefinitionId: ApiDefinitionId(apiDefId),
889
+ availability: sm.availability,
951
890
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
952
891
  noindex: void 0,
953
892
  pointsTo: void 0,
@@ -961,10 +900,9 @@ function mergeEndpointPairs(ctx, leafNodes, allNav) {
961
900
  if (route.type !== "rest") {
962
901
  continue;
963
902
  }
964
- const pairKey = metaStr(route.metadata, "endpointPairKey");
965
- const endpointId = metaStr(route.metadata, "endpointId");
966
- if (pairKey != null && endpointId != null) {
967
- endpointIdToPairKey.set(endpointId, pairKey);
903
+ const md = routeMeta(route);
904
+ if (md.endpointPairKey != null && md.endpointId != null) {
905
+ endpointIdToPairKey.set(md.endpointId, md.endpointPairKey);
968
906
  }
969
907
  }
970
908
  if (endpointIdToPairKey.size === 0) {
@@ -1006,30 +944,30 @@ function mergeEndpointPairs(ctx, leafNodes, allNav) {
1006
944
  }
1007
945
  return result;
1008
946
  }
1009
- function apiReferenceNode(ctx, scoped, scopeSegs) {
1010
- const { seg, nav } = scoped;
947
+ function apiReferenceNode(ctx, scoped, scopeSegs, sectionPaths) {
948
+ const { seg, meta: sm, nav } = scoped;
1011
949
  const overview = overviewRoute(nav);
1012
- const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
1013
- const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? "";
1014
- const slug = ctx.contentSlug(overview?.fullPath ?? nav[0]?.fullPath ?? seg.section);
1015
- const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId);
950
+ const overviewPageId = overview?.meta.pageId;
951
+ const apiDefId = sm.apiDefinitionId ?? "";
952
+ const slug = ctx.contentSlug(overview?.route.fullPath ?? nav[0]?.fullPath ?? seg.section);
953
+ const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefId, sectionPaths);
1016
954
  return {
1017
955
  type: "apiReference",
1018
956
  ...withMetadataDefaults({
1019
957
  id: ctx.nodeId(`api:${slug}`),
1020
- title: metaStr(seg.metadata, "title") ?? "",
958
+ title: sm.title ?? "",
1021
959
  slug,
1022
- icon: metaStr(seg.metadata, "icon"),
960
+ icon: sm.icon,
1023
961
  hidden: seg.hidden,
1024
962
  viewers: mergeVariantViewers(seg)
1025
963
  }),
1026
- apiDefinitionId: ApiDefinitionId(apiDefinitionId),
964
+ apiDefinitionId: ApiDefinitionId(apiDefId),
1027
965
  availability: void 0,
1028
966
  overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
1029
967
  noindex: void 0,
1030
968
  paginated: true,
1031
- showErrors: metaBool(seg.metadata, "showErrors"),
1032
- hideTitle: metaBool(seg.metadata, "hideTitle"),
969
+ showErrors: sm.showErrors,
970
+ hideTitle: sm.hideTitle,
1033
971
  pointsTo: void 0,
1034
972
  children,
1035
973
  changelog: void 0,
@@ -1038,29 +976,29 @@ function apiReferenceNode(ctx, scoped, scopeSegs) {
1038
976
  };
1039
977
  }
1040
978
  function changelogNode(ctx, scoped) {
1041
- const { seg, nav } = scoped;
979
+ const { seg, meta: sm, nav } = scoped;
1042
980
  const overview = overviewRoute(nav);
1043
- const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
981
+ const overviewPageId = overview?.meta.pageId;
1044
982
  const entries = nav.filter((r) => r.type === "changelog");
1045
983
  const byYear = /* @__PURE__ */ new Map();
1046
984
  for (const r of entries) {
1047
- const dateStr = metaStr(r.metadata, "date");
1048
- const date = dateStr != null ? new Date(dateStr) : /* @__PURE__ */ new Date(0);
985
+ const md = routeMeta(r);
986
+ const date = md.date != null ? new Date(md.date) : /* @__PURE__ */ new Date(0);
1049
987
  const year = date.getUTCFullYear();
1050
988
  const month = date.getUTCMonth() + 1;
1051
989
  const entry = {
1052
990
  type: "changelogEntry",
1053
991
  ...withMetadataDefaults({
1054
- id: ctx.nodeId(`cl-entry:${r.fullPath ?? metaStr(r.metadata, "pageId") ?? ""}`),
1055
- title: metaStr(r.metadata, "title") ?? "",
992
+ id: ctx.nodeId(`cl-entry:${r.fullPath ?? md.pageId ?? ""}`),
993
+ title: md.title ?? "",
1056
994
  slug: ctx.contentSlug(r.fullPath ?? ""),
1057
- icon: metaStr(r.metadata, "icon"),
995
+ icon: md.icon,
1058
996
  hidden: r.hidden,
1059
- viewers: toViewers(metaStrArr(r.metadata, "viewers"))
997
+ viewers: toViewers(md.viewers)
1060
998
  }),
1061
- pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
999
+ pageId: PageId(md.pageId ?? ""),
1062
1000
  noindex: void 0,
1063
- date: dateStr ?? "",
1001
+ date: md.date ?? "",
1064
1002
  tags: void 0
1065
1003
  };
1066
1004
  let months = byYear.get(year);
@@ -1072,7 +1010,7 @@ function changelogNode(ctx, scoped) {
1072
1010
  arr.push(entry);
1073
1011
  months.set(month, arr);
1074
1012
  }
1075
- const baseSlug = ctx.contentSlug(overview?.fullPath ?? seg.section);
1013
+ const baseSlug = ctx.contentSlug(overview?.route.fullPath ?? seg.section);
1076
1014
  const years = [...byYear.entries()].sort((a, b) => b[0] - a[0]).map(([year, months]) => ({
1077
1015
  type: "changelogYear",
1078
1016
  ...withMetadataDefaults({
@@ -1100,9 +1038,9 @@ function changelogNode(ctx, scoped) {
1100
1038
  type: "changelog",
1101
1039
  ...withMetadataDefaults({
1102
1040
  id: ctx.nodeId(`changelog:${baseSlug}`),
1103
- title: metaStr(seg.metadata, "title") ?? "",
1041
+ title: sm.title ?? "",
1104
1042
  slug: baseSlug,
1105
- icon: metaStr(seg.metadata, "icon"),
1043
+ icon: sm.icon,
1106
1044
  hidden: seg.hidden,
1107
1045
  viewers: mergeVariantViewers(seg)
1108
1046
  }),
@@ -1111,46 +1049,20 @@ function changelogNode(ctx, scoped) {
1111
1049
  children: years
1112
1050
  };
1113
1051
  }
1114
- function parentSectionPath(sectionPath) {
1115
- const idx = sectionPath.lastIndexOf("/");
1116
- return idx === -1 ? "" : sectionPath.slice(0, idx);
1117
- }
1118
- function nearestExistingAncestor(sectionPath, existing) {
1119
- let current = parentSectionPath(sectionPath);
1120
- while (current !== "") {
1121
- if (existing.has(current)) {
1122
- return current;
1123
- }
1124
- current = parentSectionPath(current);
1125
- }
1126
- return "";
1127
- }
1128
- function buildSectionTree(ctx, scopeSegs, parentPath) {
1129
- const sectionPaths = new Set(scopeSegs.map((s) => s.seg.section));
1052
+ function buildSectionTree(ctx, scopeSegs, parentPath, sectionPaths) {
1130
1053
  const direct = scopeSegs.filter((s) => {
1131
1054
  const sec = s.seg.section;
1132
- const type = metaStr(s.seg.metadata, "type");
1133
- if (sec === "" || type === "tabRoot") {
1134
- return false;
1135
- }
1136
- const parent = parentSectionPath(sec);
1137
- if (parent === parentPath) {
1138
- return true;
1139
- }
1140
- if (!sectionPaths.has(parent)) {
1141
- return nearestExistingAncestor(sec, sectionPaths) === parentPath;
1142
- }
1143
- return false;
1055
+ return sec !== "" && s.meta.type !== "tabRoot" && isDirectChildOf(sec, parentPath, sectionPaths);
1144
1056
  }).sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
1145
1057
  return direct.map((s) => {
1146
- const type = metaStr(s.seg.metadata, "type");
1058
+ const { type } = s.meta;
1147
1059
  if (type === "apiReference" || type === "apiPackage") {
1148
- return apiReferenceNode(ctx, s, scopeSegs);
1060
+ return apiReferenceNode(ctx, s, scopeSegs, sectionPaths);
1149
1061
  }
1150
1062
  if (type === "changelog") {
1151
1063
  return changelogNode(ctx, s);
1152
1064
  }
1153
- return sectionNode(ctx, s, buildSectionTree(ctx, scopeSegs, s.seg.section));
1065
+ return sectionNode(ctx, s, buildSectionTree(ctx, scopeSegs, s.seg.section, sectionPaths));
1154
1066
  });
1155
1067
  }
1156
1068
  function buildSidebarRootChildren(ctx, scopeSegs) {
@@ -1158,7 +1070,7 @@ function buildSidebarRootChildren(ctx, scopeSegs) {
1158
1070
  const sectionPaths = new Set(ordered.map((s) => s.seg.section));
1159
1071
  const flat = [];
1160
1072
  for (const s of ordered) {
1161
- const type = metaStr(s.seg.metadata, "type");
1073
+ const { type } = s.meta;
1162
1074
  const sec = s.seg.section;
1163
1075
  if (type === "tabRoot" || sec === "") {
1164
1076
  for (const r of s.nav) {
@@ -1169,15 +1081,13 @@ function buildSidebarRootChildren(ctx, scopeSegs) {
1169
1081
  }
1170
1082
  continue;
1171
1083
  }
1172
- const parent = parentSectionPath(sec);
1173
- const isRootLevel = parent === "" || !sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "";
1174
- if (isRootLevel) {
1084
+ if (isDirectChildOf(sec, "", sectionPaths)) {
1175
1085
  if (type === "apiReference" || type === "apiPackage") {
1176
- flat.push(apiReferenceNode(ctx, s, scopeSegs));
1086
+ flat.push(apiReferenceNode(ctx, s, scopeSegs, sectionPaths));
1177
1087
  } else if (type === "changelog") {
1178
1088
  flat.push(changelogNode(ctx, s));
1179
1089
  } else {
1180
- flat.push(sectionNode(ctx, s, buildSectionTree(ctx, scopeSegs, sec)));
1090
+ flat.push(sectionNode(ctx, s, buildSectionTree(ctx, scopeSegs, sec, sectionPaths)));
1181
1091
  }
1182
1092
  }
1183
1093
  }
@@ -1223,10 +1133,7 @@ function buildSidebarRoot(ctx, scopeSegs) {
1223
1133
  function buildFullRootFromSegments(options) {
1224
1134
  const { basePath, title, segments, navBySegment } = options;
1225
1135
  const ctx = createBuildContext(basePath);
1226
- const scoped = segments.filter((seg) => {
1227
- const t = metaStr(seg.metadata, "type");
1228
- return t !== "files" && t !== "redirects";
1229
- }).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
1136
+ const scoped = segments.map((seg) => ({ seg, meta: segMeta(seg), nav: navBySegment.get(seg.segmentHash) ?? [] })).filter((s) => s.meta.type !== "files" && s.meta.type !== "redirects");
1230
1137
  const rootSlug = asSlug(basePath);
1231
1138
  const scopesByKey = /* @__PURE__ */ new Map();
1232
1139
  for (const s of scoped) {
@@ -1244,7 +1151,7 @@ function buildFullRootFromSegments(options) {
1244
1151
  } else if (versions.length > 0) {
1245
1152
  child = buildVersioned(ctx, versions, scoped, rootSlug, void 0);
1246
1153
  } else {
1247
- child = buildUnversioned(ctx, scoped, rootSlug, tabs.length > 0);
1154
+ child = buildUnversioned(ctx, scoped, tabs.length > 0);
1248
1155
  }
1249
1156
  let rootPointsTo;
1250
1157
  if (child.type === "productgroup") {
@@ -1254,15 +1161,20 @@ function buildFullRootFromSegments(options) {
1254
1161
  const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
1255
1162
  rootPointsTo = defaultVersion?.pointsTo;
1256
1163
  }
1257
- const root = {
1164
+ return {
1258
1165
  type: "root",
1259
1166
  version: "v2",
1260
- ...withMetadataDefaults({ id: ctx.nodeId("root"), title, slug: rootSlug, icon: void 0, hidden: void 0 }),
1167
+ ...withMetadataDefaults({
1168
+ id: ctx.nodeId("root"),
1169
+ title,
1170
+ slug: rootSlug,
1171
+ icon: void 0,
1172
+ hidden: void 0
1173
+ }),
1261
1174
  roles: void 0,
1262
1175
  pointsTo: rootPointsTo,
1263
1176
  child
1264
1177
  };
1265
- return root;
1266
1178
  }
1267
1179
  function uniqueDetails(scoped, dim) {
1268
1180
  const bySlug = /* @__PURE__ */ new Map();
@@ -1271,15 +1183,14 @@ function uniqueDetails(scoped, dim) {
1271
1183
  if (d == null) {
1272
1184
  continue;
1273
1185
  }
1274
- const slug = detailSlug(d);
1186
+ const dm = detailMeta(d);
1187
+ const slug = dm.slug ?? "";
1275
1188
  const existing = bySlug.get(slug);
1276
- if (existing == null) {
1277
- bySlug.set(slug, d);
1278
- } else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
1279
- bySlug.set(slug, d);
1189
+ if (existing == null || dm.pointsTo != null && existing.meta.pointsTo == null) {
1190
+ bySlug.set(slug, { detail: d, meta: dm });
1280
1191
  }
1281
1192
  }
1282
- return [...bySlug.values()].sort((a, b) => a.sortOrder - b.sortOrder);
1193
+ return [...bySlug.values()].map((e) => e.detail).sort((a, b) => a.sortOrder - b.sortOrder);
1283
1194
  }
1284
1195
  function scopeSlugPrefix(rootSlug, ...details) {
1285
1196
  const parts = [rootSlug];
@@ -1299,22 +1210,22 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent) {
1299
1210
  }
1300
1211
  const tabDetails = uniqueDetails(scopeSegs, "tab");
1301
1212
  const children = tabDetails.map((tab) => {
1302
- const tabType = metaStr(tab.metadata, "tab_type");
1213
+ const tm = detailMeta(tab);
1303
1214
  const tabSlug = asSlug(scopeSlugPrefix(Slug(""), tab));
1304
- if (tabType === "link") {
1215
+ if (tm.tab_type === "link") {
1305
1216
  return {
1306
1217
  type: "link",
1307
- id: ctx.nodeId(`link:${metaStr(tab.metadata, "url") ?? tabSlug}`),
1218
+ id: ctx.nodeId(`link:${tm.url ?? tabSlug}`),
1308
1219
  collapsed: void 0,
1309
1220
  title: tab.displayName,
1310
1221
  icon: tab.icon ?? void 0,
1311
- url: Url(metaStr(tab.metadata, "url") ?? ""),
1222
+ url: Url(tm.url ?? ""),
1312
1223
  target: void 0
1313
1224
  };
1314
1225
  }
1315
- if (tabType === "changelog") {
1226
+ if (tm.tab_type === "changelog") {
1316
1227
  const tabSegs2 = scopeSegs.filter((s) => s.seg.tab?.id === tab.id);
1317
- const changelogSeg = tabSegs2.find((s) => metaStr(s.seg.metadata, "type") === "changelog");
1228
+ const changelogSeg = tabSegs2.find((s) => s.meta.type === "changelog");
1318
1229
  if (changelogSeg != null) {
1319
1230
  return changelogNode(ctx, changelogSeg);
1320
1231
  }
@@ -1334,7 +1245,6 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent) {
1334
1245
  };
1335
1246
  }
1336
1247
  const tabSegs = scopeSegs.filter((s) => s.seg.tab?.id === tab.id);
1337
- const metaPointsTo = metaStr(tab.metadata, "pointsTo");
1338
1248
  return {
1339
1249
  type: "tab",
1340
1250
  ...withMetadataDefaults({
@@ -1345,7 +1255,7 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent) {
1345
1255
  hidden: tab.hidden,
1346
1256
  viewers: toViewers(tab.viewers)
1347
1257
  }),
1348
- pointsTo: metaPointsTo != null ? ctx.contentSlug(metaPointsTo) : void 0,
1258
+ pointsTo: pointsToSlug(ctx, tm),
1349
1259
  child: buildSidebarRoot(ctx, tabSegs)
1350
1260
  };
1351
1261
  });
@@ -1357,8 +1267,7 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent) {
1357
1267
  children
1358
1268
  };
1359
1269
  }
1360
- function buildUnversioned(ctx, scopeSegs, rootSlug, tabsPresent) {
1361
- void rootSlug;
1270
+ function buildUnversioned(ctx, scopeSegs, tabsPresent) {
1362
1271
  const first = scopeSegs[0];
1363
1272
  return {
1364
1273
  type: "unversioned",
@@ -1370,11 +1279,12 @@ function buildUnversioned(ctx, scopeSegs, rootSlug, tabsPresent) {
1370
1279
  }
1371
1280
  function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1372
1281
  const children = versions.map((version) => {
1282
+ const vm = detailMeta(version);
1373
1283
  const versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
1374
1284
  const tabsPresent = uniqueDetails(versionSegs, "tab").length > 0;
1375
- const prefix = productPrefix != null ? productPrefix : rootSlug;
1376
- const slug = version.metadata != null && detailIsDefault(version) ? prefix : scopeSlugPrefix(rootSlug, version);
1377
- const node = {
1285
+ const prefix = productPrefix ?? rootSlug;
1286
+ const slug = vm.default ? prefix : scopeSlugPrefix(rootSlug, version);
1287
+ return {
1378
1288
  type: "version",
1379
1289
  ...withMetadataDefaults({
1380
1290
  id: ctx.nodeId(`version:${slug}`),
@@ -1384,15 +1294,14 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1384
1294
  hidden: version.hidden,
1385
1295
  viewers: toViewers(version.viewers)
1386
1296
  }),
1387
- default: detailIsDefault(version),
1297
+ default: vm.default ?? false,
1388
1298
  versionId: VersionId(version.id),
1389
1299
  availability: void 0,
1390
1300
  landingPage: void 0,
1391
1301
  announcement: void 0,
1392
- pointsTo: metaStr(version.metadata, "pointsTo") != null ? ctx.contentSlug(metaStr(version.metadata, "pointsTo")) : void 0,
1302
+ pointsTo: pointsToSlug(ctx, vm),
1393
1303
  child: buildTabbedOrSidebar(ctx, versionSegs, tabsPresent)
1394
1304
  };
1395
- return node;
1396
1305
  });
1397
1306
  return {
1398
1307
  type: "versioned",
@@ -1403,12 +1312,13 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
1403
1312
  }
1404
1313
  function buildProductGroup(ctx, products, scoped, rootSlug) {
1405
1314
  const children = products.map((product) => {
1315
+ const pm = detailMeta(product);
1406
1316
  const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
1407
1317
  const versions = uniqueDetails(productSegs, "version");
1408
1318
  const tabsPresent = uniqueDetails(productSegs, "tab").length > 0;
1409
1319
  const productPrefix = scopeSlugPrefix(rootSlug, product);
1410
- const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix) : buildUnversioned(ctx, productSegs, rootSlug, tabsPresent);
1411
- const node = {
1320
+ const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix) : buildUnversioned(ctx, productSegs, tabsPresent);
1321
+ return {
1412
1322
  type: "product",
1413
1323
  ...withMetadataDefaults({
1414
1324
  id: ctx.nodeId(`product:${productPrefix}`),
@@ -1420,13 +1330,12 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
1420
1330
  }),
1421
1331
  default: detailIsDefault(product),
1422
1332
  productId: ProductId(product.id),
1423
- subtitle: metaStr(product.metadata, "subtitle") ?? "",
1333
+ subtitle: pm.subtitle ?? "",
1424
1334
  image: void 0,
1425
1335
  announcement: void 0,
1426
- pointsTo: metaStr(product.metadata, "pointsTo") != null ? ctx.contentSlug(metaStr(product.metadata, "pointsTo")) : void 0,
1336
+ pointsTo: pointsToSlug(ctx, pm),
1427
1337
  child: productChild
1428
1338
  };
1429
- return node;
1430
1339
  });
1431
1340
  return {
1432
1341
  type: "productgroup",