@fern-api/fdr-sdk 1.2.38-cc77d6a840 → 1.2.39-2432856e2e
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.
- package/dist/js/client/FdrClient.js +28 -7
- package/dist/js/client/FdrClient.js.map +1 -1
- package/dist/js/client/FdrClient.mjs +28 -7
- package/dist/js/client/FdrClient.mjs.map +1 -1
- package/dist/js/index.js +28 -7
- package/dist/js/index.js.map +1 -1
- package/dist/js/index.mjs +28 -7
- package/dist/js/index.mjs.map +1 -1
- package/dist/js/navigation/ledger-root-builder.js +465 -64
- package/dist/js/navigation/ledger-root-builder.js.map +1 -1
- package/dist/js/navigation/ledger-root-builder.mjs +465 -64
- package/dist/js/navigation/ledger-root-builder.mjs.map +1 -1
- package/dist/js/orpc-client.js +30 -7
- package/dist/js/orpc-client.js.map +1 -1
- package/dist/js/orpc-client.mjs +30 -7
- package/dist/js/orpc-client.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/navigation/__test__/ledger-root-builder.apiReferenceChildren.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.apiReferenceChildren.test.d.ts.map +1 -0
- package/dist/types/navigation/__test__/ledger-root-builder.landingPage.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.landingPage.test.d.ts.map +1 -0
- package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.metadataPreservation.test.d.ts.map +1 -0
- package/dist/types/navigation/__test__/ledger-root-builder.rootSlug.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.rootSlug.test.d.ts.map +1 -0
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugTabs.test.d.ts.map +1 -0
- package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts +2 -0
- package/dist/types/navigation/__test__/ledger-root-builder.unversionedPointsTo.test.d.ts.map +1 -0
- package/dist/types/navigation/ledger-root-builder.d.ts +12 -0
- package/dist/types/navigation/ledger-root-builder.d.ts.map +1 -1
- package/dist/types/orpc-client/docs-ledger/contract.d.ts +2190 -170
- package/dist/types/orpc-client/docs-ledger/contract.d.ts.map +1 -1
- package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts +3456 -104
- package/dist/types/orpc-client/docs-ledger/ledger-manifest.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -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
|
});
|
|
@@ -657,6 +660,77 @@ function getChildren(node) {
|
|
|
657
660
|
}
|
|
658
661
|
}
|
|
659
662
|
|
|
663
|
+
// ../commons/core-utils/dist/assertNever.js
|
|
664
|
+
function assertNever(x) {
|
|
665
|
+
throw new Error("Unexpected value: " + JSON.stringify(x));
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// ../commons/core-utils/dist/visitDiscriminatedUnion.js
|
|
669
|
+
function visitDiscriminatedUnion(item, discriminant = "type") {
|
|
670
|
+
return {
|
|
671
|
+
_visit: (visitor) => {
|
|
672
|
+
const visit = visitor[item[discriminant]];
|
|
673
|
+
if (visit != null) {
|
|
674
|
+
return visit(item);
|
|
675
|
+
} else {
|
|
676
|
+
if (visitor._other == null) {
|
|
677
|
+
assertNever(item);
|
|
678
|
+
}
|
|
679
|
+
return visitor._other(item);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
var visitDiscriminatedUnion_default = visitDiscriminatedUnion;
|
|
685
|
+
|
|
686
|
+
// src/navigation/versions/latest/getPageId.ts
|
|
687
|
+
var RETURN_PAGEID = (node) => node.pageId;
|
|
688
|
+
var RETURN_OVERVIEW_PAGEID = (node) => node.overviewPageId;
|
|
689
|
+
var RETURN_UNDEFINED = () => void 0;
|
|
690
|
+
function getPageId(node) {
|
|
691
|
+
return visitDiscriminatedUnion_default(node)._visit({
|
|
692
|
+
section: RETURN_OVERVIEW_PAGEID,
|
|
693
|
+
apiReference: RETURN_OVERVIEW_PAGEID,
|
|
694
|
+
changelog: RETURN_OVERVIEW_PAGEID,
|
|
695
|
+
apiPackage: RETURN_OVERVIEW_PAGEID,
|
|
696
|
+
changelogEntry: RETURN_PAGEID,
|
|
697
|
+
page: RETURN_PAGEID,
|
|
698
|
+
landingPage: RETURN_PAGEID,
|
|
699
|
+
// if the following changes, make sure to update the algolia records generator
|
|
700
|
+
endpoint: RETURN_UNDEFINED,
|
|
701
|
+
webSocket: RETURN_UNDEFINED,
|
|
702
|
+
webhook: RETURN_UNDEFINED,
|
|
703
|
+
grpc: RETURN_UNDEFINED,
|
|
704
|
+
graphql: RETURN_UNDEFINED,
|
|
705
|
+
graphqlType: RETURN_UNDEFINED
|
|
706
|
+
// changelogYear: RETURN_UNDEFINED,
|
|
707
|
+
// changelogMonth: RETURN_UNDEFINED,
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// src/navigation/versions/latest/NavigationNodeSection.ts
|
|
712
|
+
function isSection(node) {
|
|
713
|
+
return node.type === "section" || node.type === "apiReference" || node.type === "changelog" || node.type === "apiPackage";
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// src/navigation/versions/latest/NavigationNodeSectionOverview.ts
|
|
717
|
+
function isSectionOverview(node) {
|
|
718
|
+
return isSection(node) && node.overviewPageId != null;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// src/navigation/versions/latest/NavigationNodeMarkdown.ts
|
|
722
|
+
function hasMarkdown(node) {
|
|
723
|
+
return isMarkdownLeaf(node) || isSectionOverview(node);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// src/navigation/versions/latest/NavigationNodePage.ts
|
|
727
|
+
function isPage(node) {
|
|
728
|
+
return isApiLeaf(node) || node.type === "changelog" || // TODO: Uncomment when changelog years and months are visitable
|
|
729
|
+
// node.type === "changelogYear" ||
|
|
730
|
+
// node.type === "changelogMonth" ||
|
|
731
|
+
hasMarkdown(node);
|
|
732
|
+
}
|
|
733
|
+
|
|
660
734
|
// src/navigation/versions/latest/NavigationNodeWithMetadata.ts
|
|
661
735
|
function hasMetadata(node) {
|
|
662
736
|
return typeof node.title === "string" && typeof node.slug === "string";
|
|
@@ -794,6 +868,13 @@ function metaStrArr(metadata, key) {
|
|
|
794
868
|
}
|
|
795
869
|
return void 0;
|
|
796
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
|
+
}
|
|
797
878
|
function toViewers(viewers) {
|
|
798
879
|
if (viewers == null || viewers.length === 0) {
|
|
799
880
|
return void 0;
|
|
@@ -829,17 +910,17 @@ function scopeKey(seg) {
|
|
|
829
910
|
return [seg.product?.id ?? "", seg.version?.id ?? "", seg.variant?.id ?? "", seg.tab?.id ?? ""].join("|");
|
|
830
911
|
}
|
|
831
912
|
function withMetadataDefaults(base) {
|
|
832
|
-
const { viewers, ...rest } = base;
|
|
913
|
+
const { viewers, featureFlags, ...rest } = base;
|
|
833
914
|
return {
|
|
834
915
|
...rest,
|
|
835
916
|
canonicalSlug: void 0,
|
|
836
|
-
authed: void 0,
|
|
917
|
+
authed: base.authed === true ? true : void 0,
|
|
837
918
|
collapsed: void 0,
|
|
838
919
|
// Normalise empty arrays to undefined so unrestricted nodes don't add
|
|
839
920
|
// filter-level noise; a non-empty array engages the RBAC view gate.
|
|
840
921
|
viewers: viewers != null && viewers.length > 0 ? viewers : void 0,
|
|
841
|
-
orphaned: void 0,
|
|
842
|
-
featureFlags: void 0
|
|
922
|
+
orphaned: base.orphaned === true ? true : void 0,
|
|
923
|
+
featureFlags: featureFlags != null && featureFlags.length > 0 ? featureFlags : void 0
|
|
843
924
|
};
|
|
844
925
|
}
|
|
845
926
|
function artifactToNode(ctx, route) {
|
|
@@ -862,7 +943,10 @@ function artifactToNode(ctx, route) {
|
|
|
862
943
|
slug,
|
|
863
944
|
icon,
|
|
864
945
|
hidden: route.hidden,
|
|
865
|
-
|
|
946
|
+
authed: metaBool(md, "authed"),
|
|
947
|
+
viewers,
|
|
948
|
+
orphaned: metaBool(md, "orphaned"),
|
|
949
|
+
featureFlags: metaFeatureFlags(md)
|
|
866
950
|
}),
|
|
867
951
|
pageId: PageId(pageId),
|
|
868
952
|
noindex: metaBool(md, "noindex"),
|
|
@@ -878,7 +962,7 @@ function artifactToNode(ctx, route) {
|
|
|
878
962
|
title,
|
|
879
963
|
icon,
|
|
880
964
|
url: Url(metaStr(md, "url") ?? ""),
|
|
881
|
-
target:
|
|
965
|
+
target: metaStr(md, "target")
|
|
882
966
|
};
|
|
883
967
|
return node;
|
|
884
968
|
}
|
|
@@ -913,7 +997,10 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
913
997
|
slug,
|
|
914
998
|
icon,
|
|
915
999
|
hidden: route.hidden,
|
|
916
|
-
|
|
1000
|
+
authed: metaBool(md, "authed"),
|
|
1001
|
+
viewers,
|
|
1002
|
+
orphaned: metaBool(md, "orphaned"),
|
|
1003
|
+
featureFlags: metaFeatureFlags(md)
|
|
917
1004
|
});
|
|
918
1005
|
if (route.type === "rest") {
|
|
919
1006
|
const endpointId = metaStr(md, "endpointId");
|
|
@@ -928,7 +1015,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
928
1015
|
endpointId: EndpointId(endpointId),
|
|
929
1016
|
apiDefinitionId,
|
|
930
1017
|
isResponseStream: metaBool(md, "isResponseStream"),
|
|
931
|
-
availability:
|
|
1018
|
+
availability: metaStr(md, "availability"),
|
|
932
1019
|
playground: void 0
|
|
933
1020
|
};
|
|
934
1021
|
}
|
|
@@ -944,7 +1031,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
944
1031
|
method,
|
|
945
1032
|
webhookId: WebhookId(webhookId),
|
|
946
1033
|
apiDefinitionId,
|
|
947
|
-
availability:
|
|
1034
|
+
availability: metaStr(md, "availability")
|
|
948
1035
|
};
|
|
949
1036
|
}
|
|
950
1037
|
if (route.type === "asyncapi") {
|
|
@@ -957,7 +1044,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
957
1044
|
...meta,
|
|
958
1045
|
webSocketId: WebSocketId(webSocketId),
|
|
959
1046
|
apiDefinitionId,
|
|
960
|
-
availability:
|
|
1047
|
+
availability: metaStr(md, "availability"),
|
|
961
1048
|
playground: void 0
|
|
962
1049
|
};
|
|
963
1050
|
}
|
|
@@ -973,7 +1060,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
973
1060
|
method,
|
|
974
1061
|
grpcId: GrpcId(grpcId),
|
|
975
1062
|
apiDefinitionId,
|
|
976
|
-
availability:
|
|
1063
|
+
availability: metaStr(md, "availability")
|
|
977
1064
|
};
|
|
978
1065
|
}
|
|
979
1066
|
if (route.type === "graphql") {
|
|
@@ -989,12 +1076,69 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2) {
|
|
|
989
1076
|
graphqlOperationId: GraphQlOperationId(graphqlOperationId),
|
|
990
1077
|
graphqlOperationIds: void 0,
|
|
991
1078
|
apiDefinitionId,
|
|
992
|
-
availability:
|
|
1079
|
+
availability: metaStr(md, "availability"),
|
|
993
1080
|
playground: void 0
|
|
994
1081
|
};
|
|
995
1082
|
}
|
|
996
1083
|
return void 0;
|
|
997
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
|
+
}
|
|
998
1142
|
function collectApiLeafNodesFromNav(routes, basePath, segmentApiDefinitionId2) {
|
|
999
1143
|
const ctx = createBuildContext(basePath);
|
|
1000
1144
|
return routes.map((route) => apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId2)).filter((node) => node != null);
|
|
@@ -1084,8 +1228,9 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
|
|
|
1084
1228
|
const { seg, nav } = scoped;
|
|
1085
1229
|
const overview = overviewRoute(nav) ?? overviewRouteFromSegmentMeta(seg, nav);
|
|
1086
1230
|
const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
|
|
1087
|
-
|
|
1088
|
-
|
|
1231
|
+
const relSection = stripLeadingScopePrefix(seg.section, scopePrefix);
|
|
1232
|
+
let slug = structuralNodeSlug(ctx, overview?.fullPath, relSection, scopePrefix);
|
|
1233
|
+
if (relSection === "" && overview?.fullPath == null) {
|
|
1089
1234
|
slug = inferSectionSlugFromNav(ctx, nav, scopePrefix) ?? slug;
|
|
1090
1235
|
}
|
|
1091
1236
|
const metaPointsTo = metaStr(seg.metadata, "pointsTo");
|
|
@@ -1095,17 +1240,22 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
|
|
|
1095
1240
|
slug,
|
|
1096
1241
|
icon: metaStr(seg.metadata, "icon"),
|
|
1097
1242
|
hidden: seg.hidden,
|
|
1098
|
-
|
|
1243
|
+
authed: metaBool(seg.metadata, "authed"),
|
|
1244
|
+
viewers: mergeVariantViewers(seg),
|
|
1245
|
+
orphaned: metaBool(seg.metadata, "orphaned"),
|
|
1246
|
+
featureFlags: metaFeatureFlags(seg.metadata)
|
|
1099
1247
|
});
|
|
1100
1248
|
return {
|
|
1101
1249
|
type: "section",
|
|
1102
1250
|
...defaults,
|
|
1103
|
-
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,
|
|
1104
1254
|
overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
|
|
1105
|
-
noindex:
|
|
1255
|
+
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
1106
1256
|
collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) != null ? true : void 0),
|
|
1107
1257
|
collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : void 0),
|
|
1108
|
-
availability:
|
|
1258
|
+
availability: metaStr(seg.metadata, "availability"),
|
|
1109
1259
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
|
|
1110
1260
|
children: mergeChildrenByPosition(ctx, nav, sectionChildren)
|
|
1111
1261
|
};
|
|
@@ -1128,8 +1278,7 @@ function directChildApiPackages(parentSection, scopeSegs) {
|
|
|
1128
1278
|
}
|
|
1129
1279
|
function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix) {
|
|
1130
1280
|
const { seg, nav } = scoped;
|
|
1131
|
-
const
|
|
1132
|
-
const leafNodes = mergeEndpointPairs(ctx, rawLeafNodes, nav);
|
|
1281
|
+
const leafNodes = positionedApiLeafChildren(ctx, nav, apiDefinitionId);
|
|
1133
1282
|
const childPackages = directChildApiPackages(seg.section, scopeSegs);
|
|
1134
1283
|
const packageNodes = childPackages.map((child) => ({
|
|
1135
1284
|
node: apiPackageChildNode(
|
|
@@ -1143,18 +1292,10 @@ function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix)
|
|
|
1143
1292
|
}));
|
|
1144
1293
|
const hasChildIndex = packageNodes.some((p) => p.childIndex != null);
|
|
1145
1294
|
if (!hasChildIndex) {
|
|
1146
|
-
return [...leafNodes, ...packageNodes.map((p) => p.node)];
|
|
1147
|
-
}
|
|
1148
|
-
const leafPositions = [];
|
|
1149
|
-
for (const route of nav) {
|
|
1150
|
-
if (route.displaySortOrder != null) {
|
|
1151
|
-
leafPositions.push(route.displaySortOrder);
|
|
1152
|
-
}
|
|
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);
|
|
1153
1296
|
}
|
|
1154
1297
|
const positioned = [];
|
|
1155
|
-
|
|
1156
|
-
positioned.push({ node: leafNodes[i], pos: leafPositions[i] ?? i });
|
|
1157
|
-
}
|
|
1298
|
+
positioned.push(...leafNodes);
|
|
1158
1299
|
for (const p of packageNodes) {
|
|
1159
1300
|
positioned.push({ node: p.node, pos: p.childIndex ?? Number.MAX_SAFE_INTEGER });
|
|
1160
1301
|
}
|
|
@@ -1166,7 +1307,12 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
|
|
|
1166
1307
|
const overview = overviewRoute(nav);
|
|
1167
1308
|
const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
|
|
1168
1309
|
const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? parentApiDefinitionId;
|
|
1169
|
-
const slug = structuralNodeSlug(
|
|
1310
|
+
const slug = structuralNodeSlug(
|
|
1311
|
+
ctx,
|
|
1312
|
+
overview?.fullPath,
|
|
1313
|
+
stripLeadingScopePrefix(seg.section, scopePrefix),
|
|
1314
|
+
scopePrefix
|
|
1315
|
+
);
|
|
1170
1316
|
const metaPointsTo = metaStr(seg.metadata, "pointsTo");
|
|
1171
1317
|
const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
|
|
1172
1318
|
return {
|
|
@@ -1177,12 +1323,15 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
|
|
|
1177
1323
|
slug,
|
|
1178
1324
|
icon: metaStr(seg.metadata, "icon"),
|
|
1179
1325
|
hidden: seg.hidden,
|
|
1180
|
-
|
|
1326
|
+
authed: metaBool(seg.metadata, "authed"),
|
|
1327
|
+
viewers: toViewers(metaStrArr(seg.metadata, "viewers")),
|
|
1328
|
+
orphaned: metaBool(seg.metadata, "orphaned"),
|
|
1329
|
+
featureFlags: metaFeatureFlags(seg.metadata)
|
|
1181
1330
|
}),
|
|
1182
1331
|
apiDefinitionId: ApiDefinitionId(apiDefinitionId),
|
|
1183
1332
|
availability: metaStr(seg.metadata, "availability"),
|
|
1184
1333
|
overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
|
|
1185
|
-
noindex:
|
|
1334
|
+
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
1186
1335
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
|
|
1187
1336
|
children,
|
|
1188
1337
|
playground: void 0
|
|
@@ -1245,7 +1394,12 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
|
|
|
1245
1394
|
const overview = overviewRoute(nav);
|
|
1246
1395
|
const overviewPageId = overview != null ? metaStr(overview.metadata, "pageId") : void 0;
|
|
1247
1396
|
const apiDefinitionId = metaStr(seg.metadata, "apiDefinitionId") ?? "";
|
|
1248
|
-
const slug = structuralNodeSlug(
|
|
1397
|
+
const slug = structuralNodeSlug(
|
|
1398
|
+
ctx,
|
|
1399
|
+
overview?.fullPath,
|
|
1400
|
+
stripLeadingScopePrefix(seg.section, scopePrefix),
|
|
1401
|
+
scopePrefix
|
|
1402
|
+
);
|
|
1249
1403
|
const metaPointsTo = metaStr(seg.metadata, "pointsTo");
|
|
1250
1404
|
const children = buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
|
|
1251
1405
|
const changelog = attachedApiChangelogNode(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix);
|
|
@@ -1257,12 +1411,15 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
|
|
|
1257
1411
|
slug,
|
|
1258
1412
|
icon: metaStr(seg.metadata, "icon"),
|
|
1259
1413
|
hidden: seg.hidden,
|
|
1260
|
-
|
|
1414
|
+
authed: metaBool(seg.metadata, "authed"),
|
|
1415
|
+
viewers: mergeVariantViewers(seg),
|
|
1416
|
+
orphaned: metaBool(seg.metadata, "orphaned"),
|
|
1417
|
+
featureFlags: metaFeatureFlags(seg.metadata)
|
|
1261
1418
|
}),
|
|
1262
1419
|
apiDefinitionId: ApiDefinitionId(apiDefinitionId),
|
|
1263
|
-
availability:
|
|
1420
|
+
availability: metaStr(seg.metadata, "availability"),
|
|
1264
1421
|
overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
|
|
1265
|
-
noindex:
|
|
1422
|
+
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
1266
1423
|
paginated: true,
|
|
1267
1424
|
showErrors: metaBool(seg.metadata, "showErrors"),
|
|
1268
1425
|
hideTitle: metaBool(seg.metadata, "hideTitle"),
|
|
@@ -1315,12 +1472,15 @@ function changelogNode(ctx, scoped, scopePrefix) {
|
|
|
1315
1472
|
slug: ctx.contentSlug(r.fullPath ?? ""),
|
|
1316
1473
|
icon: metaStr(r.metadata, "icon"),
|
|
1317
1474
|
hidden: r.hidden,
|
|
1318
|
-
|
|
1475
|
+
authed: metaBool(r.metadata, "authed"),
|
|
1476
|
+
viewers: toViewers(metaStrArr(r.metadata, "viewers")),
|
|
1477
|
+
orphaned: metaBool(r.metadata, "orphaned"),
|
|
1478
|
+
featureFlags: metaFeatureFlags(r.metadata)
|
|
1319
1479
|
}),
|
|
1320
1480
|
pageId: PageId(metaStr(r.metadata, "pageId") ?? ""),
|
|
1321
|
-
noindex:
|
|
1481
|
+
noindex: metaBool(r.metadata, "noindex"),
|
|
1322
1482
|
date: dateStr ?? "",
|
|
1323
|
-
tags:
|
|
1483
|
+
tags: metaStrArr(r.metadata, "tags")
|
|
1324
1484
|
};
|
|
1325
1485
|
let months = byYear.get(year);
|
|
1326
1486
|
if (months == null) {
|
|
@@ -1364,10 +1524,13 @@ function changelogNode(ctx, scoped, scopePrefix) {
|
|
|
1364
1524
|
slug: baseSlug,
|
|
1365
1525
|
icon: metaStr(seg.metadata, "icon"),
|
|
1366
1526
|
hidden: seg.hidden,
|
|
1367
|
-
|
|
1527
|
+
authed: metaBool(seg.metadata, "authed"),
|
|
1528
|
+
viewers: mergeVariantViewers(seg),
|
|
1529
|
+
orphaned: metaBool(seg.metadata, "orphaned"),
|
|
1530
|
+
featureFlags: metaFeatureFlags(seg.metadata)
|
|
1368
1531
|
}),
|
|
1369
1532
|
overviewPageId: overviewPageId != null ? PageId(overviewPageId) : void 0,
|
|
1370
|
-
noindex:
|
|
1533
|
+
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
1371
1534
|
children: years
|
|
1372
1535
|
};
|
|
1373
1536
|
}
|
|
@@ -1424,17 +1587,55 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
|
|
|
1424
1587
|
return { node, childIndex };
|
|
1425
1588
|
});
|
|
1426
1589
|
}
|
|
1590
|
+
function computeSiblingSortBoundaries(ordered) {
|
|
1591
|
+
const result = /* @__PURE__ */ new Map();
|
|
1592
|
+
const sectionPaths = new Set(ordered.map((s) => s.seg.section));
|
|
1593
|
+
const rootSections = [];
|
|
1594
|
+
for (const s of ordered) {
|
|
1595
|
+
const type = metaStr(s.seg.metadata, "type");
|
|
1596
|
+
const sec = s.seg.section;
|
|
1597
|
+
if (type !== "section" || sec === "") {
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1600
|
+
const parent = parentSectionPath(sec);
|
|
1601
|
+
const isRootLevel = parent === "" || !sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "";
|
|
1602
|
+
if (isRootLevel) {
|
|
1603
|
+
rootSections.push(s);
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
1607
|
+
for (const s of rootSections) {
|
|
1608
|
+
const group = byPath.get(s.seg.section) ?? [];
|
|
1609
|
+
group.push(s);
|
|
1610
|
+
byPath.set(s.seg.section, group);
|
|
1611
|
+
}
|
|
1612
|
+
for (const [, siblings] of byPath) {
|
|
1613
|
+
if (siblings.length <= 1) {
|
|
1614
|
+
continue;
|
|
1615
|
+
}
|
|
1616
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
1617
|
+
const lo = siblings[i].seg.sortOrder;
|
|
1618
|
+
const hi = i + 1 < siblings.length ? siblings[i + 1].seg.sortOrder : Number.MAX_SAFE_INTEGER;
|
|
1619
|
+
result.set(siblings[i], { lo, hi });
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
return result;
|
|
1623
|
+
}
|
|
1427
1624
|
function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
|
|
1428
1625
|
const ordered = [...scopeSegs].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
|
|
1429
1626
|
const sectionPaths = new Set(ordered.map((s) => s.seg.section));
|
|
1430
1627
|
const annotated = [];
|
|
1431
1628
|
const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" && s.seg.section === "");
|
|
1629
|
+
const siblingBoundaries = computeSiblingSortBoundaries(ordered);
|
|
1432
1630
|
for (const s of ordered) {
|
|
1433
1631
|
const type = metaStr(s.seg.metadata, "type");
|
|
1434
1632
|
const sec = s.seg.section;
|
|
1435
1633
|
if (hasOwningApiReference(s, scopeSegs)) {
|
|
1436
1634
|
continue;
|
|
1437
1635
|
}
|
|
1636
|
+
if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1438
1639
|
if (type === "tabRoot" || sec === "" && type !== "section") {
|
|
1439
1640
|
for (const r of s.nav) {
|
|
1440
1641
|
const node = artifactToNode(ctx, r);
|
|
@@ -1462,14 +1663,21 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
|
|
|
1462
1663
|
} else if (type === "changelog") {
|
|
1463
1664
|
node = changelogNode(ctx, s, changelogScopePrefix ?? scopePrefix);
|
|
1464
1665
|
} else {
|
|
1666
|
+
const bounds = siblingBoundaries.get(s);
|
|
1667
|
+
const ownedSegs = bounds != null ? scopeSegs.filter((seg) => seg.seg.sortOrder >= bounds.lo && seg.seg.sortOrder < bounds.hi) : scopeSegs;
|
|
1465
1668
|
node = sectionNode(
|
|
1466
1669
|
ctx,
|
|
1467
1670
|
s,
|
|
1468
|
-
buildSectionTree(ctx,
|
|
1671
|
+
buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix),
|
|
1469
1672
|
scopePrefix
|
|
1470
1673
|
);
|
|
1471
1674
|
}
|
|
1472
|
-
|
|
1675
|
+
const isSharedSection = siblingBoundaries.size > 0 && scopePrefix !== "" && sec !== "" && !sec.startsWith(scopePrefix);
|
|
1676
|
+
annotated.push({
|
|
1677
|
+
node,
|
|
1678
|
+
pos: isSharedSection ? void 0 : metaNum(s.seg.metadata, "childIndex"),
|
|
1679
|
+
isLeaf: false
|
|
1680
|
+
});
|
|
1473
1681
|
}
|
|
1474
1682
|
}
|
|
1475
1683
|
const hasLeafPos = annotated.some((a) => a.isLeaf && a.pos != null);
|
|
@@ -1521,13 +1729,13 @@ function buildSidebarRoot(ctx, scopeSegs, scopePrefix, changelogScopePrefix) {
|
|
|
1521
1729
|
};
|
|
1522
1730
|
}
|
|
1523
1731
|
function buildFullRootFromSegments(options) {
|
|
1524
|
-
const { basePath, title, segments, navBySegment } = options;
|
|
1732
|
+
const { basePath, rootSlug: sourceRootSlug, title, segments, navBySegment, skipSharedSectionMerge } = options;
|
|
1525
1733
|
const ctx = createBuildContext(basePath);
|
|
1526
1734
|
const scoped = segments.filter((seg) => {
|
|
1527
1735
|
const t = metaStr(seg.metadata, "type");
|
|
1528
1736
|
return t !== "files" && t !== "redirects";
|
|
1529
1737
|
}).map((seg) => ({ seg, nav: navBySegment.get(seg.segmentHash) ?? [] }));
|
|
1530
|
-
const rootSlug = asSlug(basePath);
|
|
1738
|
+
const rootSlug = asSlug(sourceRootSlug ?? basePath);
|
|
1531
1739
|
const scopesByKey = /* @__PURE__ */ new Map();
|
|
1532
1740
|
for (const s of scoped) {
|
|
1533
1741
|
const key = scopeKey(s.seg);
|
|
@@ -1540,9 +1748,9 @@ function buildFullRootFromSegments(options) {
|
|
|
1540
1748
|
const tabs = uniqueDetails(scoped, "tab");
|
|
1541
1749
|
let child;
|
|
1542
1750
|
if (products.length > 0) {
|
|
1543
|
-
child = buildProductGroup(ctx, products, scoped, rootSlug);
|
|
1751
|
+
child = buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge);
|
|
1544
1752
|
} else if (versions.length > 0) {
|
|
1545
|
-
child = buildVersioned(ctx, versions, scoped, rootSlug, void 0);
|
|
1753
|
+
child = buildVersioned(ctx, versions, scoped, rootSlug, void 0, skipSharedSectionMerge);
|
|
1546
1754
|
} else {
|
|
1547
1755
|
child = buildUnversioned(ctx, scoped, rootSlug, tabs.length > 0);
|
|
1548
1756
|
}
|
|
@@ -1553,6 +1761,24 @@ function buildFullRootFromSegments(options) {
|
|
|
1553
1761
|
} else if (child.type === "versioned") {
|
|
1554
1762
|
const defaultVersion = child.children.find((v) => v.default) ?? child.children[0];
|
|
1555
1763
|
rootPointsTo = defaultVersion?.pointsTo;
|
|
1764
|
+
} else if (child.type === "unversioned") {
|
|
1765
|
+
if (tabs.length > 0) {
|
|
1766
|
+
const firstTab = tabs[0];
|
|
1767
|
+
const pt = firstTab != null ? metaStr(firstTab.metadata, "pointsTo") : void 0;
|
|
1768
|
+
rootPointsTo = pt != null ? pointsToSlug(pt) : void 0;
|
|
1769
|
+
} else {
|
|
1770
|
+
const sorted = [...scoped].sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
|
|
1771
|
+
for (const s of sorted) {
|
|
1772
|
+
if (s.seg.hidden) {
|
|
1773
|
+
continue;
|
|
1774
|
+
}
|
|
1775
|
+
const pt = metaStr(s.seg.metadata, "pointsTo");
|
|
1776
|
+
if (pt != null) {
|
|
1777
|
+
rootPointsTo = pointsToSlug(pt);
|
|
1778
|
+
break;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1556
1782
|
}
|
|
1557
1783
|
const root = {
|
|
1558
1784
|
type: "root",
|
|
@@ -1565,21 +1791,22 @@ function buildFullRootFromSegments(options) {
|
|
|
1565
1791
|
return root;
|
|
1566
1792
|
}
|
|
1567
1793
|
function uniqueDetails(scoped, dim) {
|
|
1568
|
-
const
|
|
1794
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1569
1795
|
for (const s of scoped) {
|
|
1570
1796
|
const d = s.seg[dim];
|
|
1571
1797
|
if (d == null) {
|
|
1572
1798
|
continue;
|
|
1573
1799
|
}
|
|
1574
1800
|
const slug = detailSlug(d);
|
|
1575
|
-
const
|
|
1801
|
+
const key = dim === "tab" ? d.id : slug !== "" ? slug : d.id;
|
|
1802
|
+
const existing = byKey.get(key);
|
|
1576
1803
|
if (existing == null) {
|
|
1577
|
-
|
|
1804
|
+
byKey.set(key, d);
|
|
1578
1805
|
} else if (metaStr(d.metadata, "pointsTo") != null && metaStr(existing.metadata, "pointsTo") == null) {
|
|
1579
|
-
|
|
1806
|
+
byKey.set(key, d);
|
|
1580
1807
|
}
|
|
1581
1808
|
}
|
|
1582
|
-
return [...
|
|
1809
|
+
return [...byKey.values()].sort((a, b) => a.sortOrder - b.sortOrder);
|
|
1583
1810
|
}
|
|
1584
1811
|
function scopeSlugPrefix(rootSlug, ...details) {
|
|
1585
1812
|
const parts = [rootSlug];
|
|
@@ -1613,7 +1840,7 @@ function buildVariantedNode(ctx, variants, scopeSegs, scopePrefix) {
|
|
|
1613
1840
|
default: detailIsDefault(variant),
|
|
1614
1841
|
variantId: VariantId(String(variant.id)),
|
|
1615
1842
|
subtitle: metaStr(variant.metadata, "subtitle") ?? void 0,
|
|
1616
|
-
image: void 0,
|
|
1843
|
+
image: metaStr(variant.metadata, "image") != null ? FileId(metaStr(variant.metadata, "image")) : void 0,
|
|
1617
1844
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : void 0,
|
|
1618
1845
|
children
|
|
1619
1846
|
};
|
|
@@ -1650,7 +1877,10 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix) {
|
|
|
1650
1877
|
const tabDetails = uniqueDetails(scopeSegs, "tab");
|
|
1651
1878
|
const children = tabDetails.map((tab) => {
|
|
1652
1879
|
const tabType = metaStr(tab.metadata, "tab_type");
|
|
1653
|
-
const
|
|
1880
|
+
const rawTabSlug = detailSlug(tab);
|
|
1881
|
+
const versionDetail = scopeSegs[0]?.seg.version;
|
|
1882
|
+
const versionSlugStr = versionDetail != null ? detailSlug(versionDetail) : void 0;
|
|
1883
|
+
const tabSlug = versionSlugStr != null && rawTabSlug !== "" && (rawTabSlug === versionSlugStr || rawTabSlug.startsWith(versionSlugStr + "/")) ? asSlug(rawTabSlug) : asSlug(scopeSlugPrefix(scopePrefix, tab));
|
|
1654
1884
|
if (tabType === "link") {
|
|
1655
1885
|
return {
|
|
1656
1886
|
type: "link",
|
|
@@ -1659,7 +1889,7 @@ function buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix) {
|
|
|
1659
1889
|
title: tab.displayName,
|
|
1660
1890
|
icon: tab.icon ?? void 0,
|
|
1661
1891
|
url: Url(metaStr(tab.metadata, "url") ?? ""),
|
|
1662
|
-
target:
|
|
1892
|
+
target: metaStr(tab.metadata, "target")
|
|
1663
1893
|
};
|
|
1664
1894
|
}
|
|
1665
1895
|
if (tabType === "changelog") {
|
|
@@ -1720,16 +1950,71 @@ function buildUnversioned(ctx, scopeSegs, scopePrefix, tabsPresent) {
|
|
|
1720
1950
|
type: "unversioned",
|
|
1721
1951
|
id: ctx.nodeId(`unversioned:${first?.seg.product?.id ?? "root"}`),
|
|
1722
1952
|
collapsed: void 0,
|
|
1723
|
-
landingPage:
|
|
1953
|
+
landingPage: buildLandingPage(ctx, scopeSegs),
|
|
1724
1954
|
// The enclosing scope prefix (product slug, or rootSlug at the top
|
|
1725
1955
|
// level) roots structural sections so they share the scope's slug
|
|
1726
1956
|
// namespace.
|
|
1727
1957
|
child: buildTabbedOrSidebar(ctx, scopeSegs, tabsPresent, scopePrefix)
|
|
1728
1958
|
};
|
|
1729
1959
|
}
|
|
1730
|
-
function
|
|
1960
|
+
function mergeSharedSections(defaultSegs, allScoped, defaultVersion, versionSlugs) {
|
|
1961
|
+
const defaultTabsByName = /* @__PURE__ */ new Map();
|
|
1962
|
+
for (const s of defaultSegs) {
|
|
1963
|
+
if (s.seg.tab != null) {
|
|
1964
|
+
const tabName = s.seg.tab.displayName;
|
|
1965
|
+
if (!defaultTabsByName.has(tabName)) {
|
|
1966
|
+
defaultTabsByName.set(tabName, s.seg.tab);
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
const existingSections = new Set(
|
|
1971
|
+
defaultSegs.filter((s) => metaStr(s.seg.metadata, "type") === "section").map((s) => s.seg.section)
|
|
1972
|
+
);
|
|
1973
|
+
const maxSortOrder = defaultSegs.reduce((max, s) => Math.max(max, s.seg.sortOrder), 0);
|
|
1974
|
+
let nextSortOrder = maxSortOrder + 1;
|
|
1975
|
+
const merged = [...defaultSegs];
|
|
1976
|
+
for (const s of allScoped) {
|
|
1977
|
+
if (s.seg.version?.id === defaultVersion.id) {
|
|
1978
|
+
continue;
|
|
1979
|
+
}
|
|
1980
|
+
const type = metaStr(s.seg.metadata, "type");
|
|
1981
|
+
if (type !== "section") {
|
|
1982
|
+
continue;
|
|
1983
|
+
}
|
|
1984
|
+
const sectionPath = s.seg.section;
|
|
1985
|
+
if (versionSlugs.some((vs) => sectionPath === vs || sectionPath.startsWith(vs + "/"))) {
|
|
1986
|
+
continue;
|
|
1987
|
+
}
|
|
1988
|
+
if (existingSections.has(sectionPath)) {
|
|
1989
|
+
continue;
|
|
1990
|
+
}
|
|
1991
|
+
const sourceTabName = s.seg.tab?.displayName ?? "";
|
|
1992
|
+
const targetTab = defaultTabsByName.get(sourceTabName);
|
|
1993
|
+
if (targetTab == null) {
|
|
1994
|
+
continue;
|
|
1995
|
+
}
|
|
1996
|
+
const metadata = s.seg.metadata != null ? { ...s.seg.metadata, childIndex: void 0 } : s.seg.metadata;
|
|
1997
|
+
merged.push({
|
|
1998
|
+
seg: {
|
|
1999
|
+
...s.seg,
|
|
2000
|
+
tab: targetTab,
|
|
2001
|
+
version: defaultVersion,
|
|
2002
|
+
sortOrder: nextSortOrder++,
|
|
2003
|
+
metadata
|
|
2004
|
+
},
|
|
2005
|
+
nav: s.nav
|
|
2006
|
+
});
|
|
2007
|
+
existingSections.add(sectionPath);
|
|
2008
|
+
}
|
|
2009
|
+
return merged;
|
|
2010
|
+
}
|
|
2011
|
+
function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix, skipSharedSectionMerge) {
|
|
2012
|
+
const versionSlugs = versions.map((v) => detailSlug(v)).filter((s) => s !== "");
|
|
1731
2013
|
const children = versions.map((version) => {
|
|
1732
|
-
|
|
2014
|
+
let versionSegs = scoped.filter((s) => s.seg.version?.id === version.id);
|
|
2015
|
+
if (detailIsDefault(version) && !skipSharedSectionMerge) {
|
|
2016
|
+
versionSegs = mergeSharedSections(versionSegs, scoped, version, versionSlugs);
|
|
2017
|
+
}
|
|
1733
2018
|
const tabsPresent = uniqueDetails(versionSegs, "tab").length > 0;
|
|
1734
2019
|
const prefix = productPrefix != null ? productPrefix : rootSlug;
|
|
1735
2020
|
const versionSegment = detailSlug(version);
|
|
@@ -1747,7 +2032,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
|
|
|
1747
2032
|
default: detailIsDefault(version),
|
|
1748
2033
|
versionId: VersionId(version.id),
|
|
1749
2034
|
availability: void 0,
|
|
1750
|
-
landingPage:
|
|
2035
|
+
landingPage: buildLandingPage(ctx, versionSegs),
|
|
1751
2036
|
announcement: void 0,
|
|
1752
2037
|
pointsTo: metaStr(version.metadata, "pointsTo") != null ? pointsToSlug(metaStr(version.metadata, "pointsTo")) : void 0,
|
|
1753
2038
|
// The version's full slug roots structural sections so the whole
|
|
@@ -1759,6 +2044,7 @@ function buildVersioned(ctx, versions, scoped, rootSlug, productPrefix) {
|
|
|
1759
2044
|
}
|
|
1760
2045
|
return node;
|
|
1761
2046
|
});
|
|
2047
|
+
markCrossVersionCanonicalSlugs(children);
|
|
1762
2048
|
return {
|
|
1763
2049
|
type: "versioned",
|
|
1764
2050
|
id: ctx.nodeId(`versioned:${productPrefix ?? "root"}`),
|
|
@@ -1784,13 +2070,125 @@ function markDefaultVersionCanonicalSlugs(node, pruneSlug, versionSlug) {
|
|
|
1784
2070
|
return;
|
|
1785
2071
|
});
|
|
1786
2072
|
}
|
|
1787
|
-
function
|
|
2073
|
+
function unversionedParents(parents) {
|
|
2074
|
+
let versionIdx = -1;
|
|
2075
|
+
for (let i = parents.length - 1; i >= 0; i--) {
|
|
2076
|
+
if (parents[i].type === "version") {
|
|
2077
|
+
versionIdx = i;
|
|
2078
|
+
break;
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
return versionIdx >= 0 ? parents.slice(versionIdx + 1) : parents;
|
|
2082
|
+
}
|
|
2083
|
+
function crossVersionDedupKeys(node, parents) {
|
|
2084
|
+
const keys = [];
|
|
2085
|
+
const uParents = unversionedParents(parents);
|
|
2086
|
+
const pid = getPageId(node);
|
|
2087
|
+
if (pid != null) {
|
|
2088
|
+
keys.push(`pid:${pid}`);
|
|
2089
|
+
}
|
|
2090
|
+
if (node.type === "endpoint" || node.type === "webSocket" || node.type === "webhook" || node.type === "grpc" || node.type === "graphql") {
|
|
2091
|
+
const apiParentTitles = uParents.filter(
|
|
2092
|
+
(p) => p.type === "apiReference"
|
|
2093
|
+
).map((p) => p.title.replaceAll(" ", ""));
|
|
2094
|
+
const apiPrefix = apiParentTitles.join(":");
|
|
2095
|
+
if (node.type === "endpoint") {
|
|
2096
|
+
keys.push(`${apiPrefix}:api:endpoint:${node.method}:${node.endpointId}`);
|
|
2097
|
+
} else if (node.type === "webSocket") {
|
|
2098
|
+
keys.push(`${apiPrefix}:api:websocket:${node.webSocketId}`);
|
|
2099
|
+
} else if (node.type === "webhook") {
|
|
2100
|
+
keys.push(`${apiPrefix}:api:webhook:${node.method}:${node.webhookId}`);
|
|
2101
|
+
} else if (node.type === "grpc") {
|
|
2102
|
+
keys.push(`${apiPrefix}:api:grpc:${node.method}:${node.grpcId}`);
|
|
2103
|
+
} else if (node.type === "graphql") {
|
|
2104
|
+
keys.push(`${apiPrefix}:api:graphql:${node.id}`);
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
const parentTitles = [];
|
|
2108
|
+
for (const p of uParents) {
|
|
2109
|
+
if (hasMetadata(p)) {
|
|
2110
|
+
parentTitles.push(p.title);
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
keys.push([...parentTitles, node.title].join("###"));
|
|
2114
|
+
return keys;
|
|
2115
|
+
}
|
|
2116
|
+
function routeToLandingPage(ctx, route) {
|
|
2117
|
+
if (route == null || route.type !== "markdown" || route.fullPath == null) {
|
|
2118
|
+
return void 0;
|
|
2119
|
+
}
|
|
2120
|
+
const md = route.metadata;
|
|
2121
|
+
const pageId = metaStr(md, "pageId");
|
|
2122
|
+
if (pageId == null) {
|
|
2123
|
+
return void 0;
|
|
2124
|
+
}
|
|
2125
|
+
const slug = ctx.contentSlug(route.fullPath);
|
|
2126
|
+
return {
|
|
2127
|
+
type: "landingPage",
|
|
2128
|
+
...withMetadataDefaults({
|
|
2129
|
+
id: ctx.nodeId(`landing:${slug}`),
|
|
2130
|
+
title: metaStr(md, "title") ?? "",
|
|
2131
|
+
slug,
|
|
2132
|
+
icon: metaStr(md, "icon"),
|
|
2133
|
+
hidden: route.hidden,
|
|
2134
|
+
authed: metaBool(md, "authed"),
|
|
2135
|
+
viewers: toViewers(metaStrArr(md, "viewers")),
|
|
2136
|
+
orphaned: metaBool(md, "orphaned"),
|
|
2137
|
+
featureFlags: metaFeatureFlags(md)
|
|
2138
|
+
}),
|
|
2139
|
+
pageId: PageId(pageId),
|
|
2140
|
+
noindex: metaBool(md, "noindex")
|
|
2141
|
+
};
|
|
2142
|
+
}
|
|
2143
|
+
function buildLandingPage(ctx, scopeSegs) {
|
|
2144
|
+
const landingSegment = scopeSegs.find(
|
|
2145
|
+
(s) => metaStr(s.seg.metadata, "type") === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true
|
|
2146
|
+
);
|
|
2147
|
+
return routeToLandingPage(
|
|
2148
|
+
ctx,
|
|
2149
|
+
landingSegment?.nav.find((route) => route.type === "markdown")
|
|
2150
|
+
);
|
|
2151
|
+
}
|
|
2152
|
+
function markCrossVersionCanonicalSlugs(versionNodes) {
|
|
2153
|
+
const keyToCanonical = /* @__PURE__ */ new Map();
|
|
2154
|
+
const sorted = [...versionNodes].sort((a, b) => {
|
|
2155
|
+
if (a.default !== b.default) {
|
|
2156
|
+
return a.default ? -1 : 1;
|
|
2157
|
+
}
|
|
2158
|
+
return 0;
|
|
2159
|
+
});
|
|
2160
|
+
for (const version of sorted) {
|
|
2161
|
+
traverseDF(version, (child, parents) => {
|
|
2162
|
+
if (hasMetadata(child) && isPage(child)) {
|
|
2163
|
+
const keys = crossVersionDedupKeys(child, parents);
|
|
2164
|
+
let matched = false;
|
|
2165
|
+
for (const key of keys) {
|
|
2166
|
+
const canonical = keyToCanonical.get(key);
|
|
2167
|
+
if (canonical != null && !version.default) {
|
|
2168
|
+
child.canonicalSlug = canonical;
|
|
2169
|
+
matched = true;
|
|
2170
|
+
break;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
if (!matched) {
|
|
2174
|
+
const canonical = child.canonicalSlug ?? child.slug;
|
|
2175
|
+
for (const key of keys) {
|
|
2176
|
+
if (!keyToCanonical.has(key)) {
|
|
2177
|
+
keyToCanonical.set(key, canonical);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMerge) {
|
|
1788
2186
|
const children = products.map((product) => {
|
|
1789
2187
|
const productSegs = scoped.filter((s) => s.seg.product?.id === product.id);
|
|
1790
2188
|
const versions = uniqueDetails(productSegs, "version");
|
|
1791
2189
|
const tabsPresent = uniqueDetails(productSegs, "tab").length > 0;
|
|
1792
2190
|
const productPrefix = scopeSlugPrefix(rootSlug, product);
|
|
1793
|
-
const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
|
|
2191
|
+
const productChild = versions.length > 0 ? buildVersioned(ctx, versions, productSegs, rootSlug, productPrefix, skipSharedSectionMerge) : buildUnversioned(ctx, productSegs, asSlug(productPrefix), tabsPresent);
|
|
1794
2192
|
const node = {
|
|
1795
2193
|
type: "product",
|
|
1796
2194
|
...withMetadataDefaults({
|
|
@@ -1809,7 +2207,7 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
|
|
|
1809
2207
|
// here; sourcing it from the hash makes that filter match nothing.
|
|
1810
2208
|
productId: ProductId(product.displayName),
|
|
1811
2209
|
subtitle: metaStr(product.metadata, "subtitle") ?? "",
|
|
1812
|
-
image: void 0,
|
|
2210
|
+
image: metaStr(product.metadata, "image") != null ? FileId(metaStr(product.metadata, "image")) : void 0,
|
|
1813
2211
|
announcement: void 0,
|
|
1814
2212
|
pointsTo: metaStr(product.metadata, "pointsTo") != null ? pointsToSlug(metaStr(product.metadata, "pointsTo")) : void 0,
|
|
1815
2213
|
child: productChild
|
|
@@ -1820,7 +2218,10 @@ function buildProductGroup(ctx, products, scoped, rootSlug) {
|
|
|
1820
2218
|
type: "productgroup",
|
|
1821
2219
|
id: ctx.nodeId("productgroup"),
|
|
1822
2220
|
collapsed: void 0,
|
|
1823
|
-
landingPage:
|
|
2221
|
+
landingPage: buildLandingPage(
|
|
2222
|
+
ctx,
|
|
2223
|
+
scoped.filter((s) => s.seg.product == null)
|
|
2224
|
+
),
|
|
1824
2225
|
children
|
|
1825
2226
|
};
|
|
1826
2227
|
}
|