@fern-api/fdr-sdk 1.2.42-54880bfeac → 1.2.42-6d01f91096
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 +0 -1
- package/dist/js/client/FdrClient.js.map +1 -1
- package/dist/js/client/FdrClient.mjs +0 -1
- package/dist/js/client/FdrClient.mjs.map +1 -1
- package/dist/js/converters/index.js +0 -9
- package/dist/js/converters/index.js.map +1 -1
- package/dist/js/converters/index.mjs +0 -9
- package/dist/js/converters/index.mjs.map +1 -1
- package/dist/js/index.js +0 -10
- package/dist/js/index.js.map +1 -1
- package/dist/js/index.mjs +0 -10
- package/dist/js/index.mjs.map +1 -1
- package/dist/js/navigation/index.js +0 -9
- package/dist/js/navigation/index.js.map +1 -1
- package/dist/js/navigation/index.mjs +0 -9
- package/dist/js/navigation/index.mjs.map +1 -1
- package/dist/js/navigation/ledger-root-builder.js +36 -212
- package/dist/js/navigation/ledger-root-builder.js.map +1 -1
- package/dist/js/navigation/ledger-root-builder.mjs +36 -212
- package/dist/js/navigation/ledger-root-builder.mjs.map +1 -1
- package/dist/js/orpc-client.js +0 -1
- package/dist/js/orpc-client.js.map +1 -1
- package/dist/js/orpc-client.mjs +0 -1
- package/dist/js/orpc-client.mjs.map +1 -1
- package/dist/navigation/__test__/ledger-root-builder.metadataPreservation.test.js +4 -109
- package/dist/navigation/__test__/ledger-root-builder.metadataPreservation.test.js.map +1 -1
- package/dist/navigation/__test__/ledger-root-builder.rootChildOrder.test.js +0 -102
- package/dist/navigation/__test__/ledger-root-builder.rootChildOrder.test.js.map +1 -1
- package/dist/navigation/__test__/ledger-root-builder.skipSlugApiReference.test.js +0 -276
- package/dist/navigation/__test__/ledger-root-builder.skipSlugApiReference.test.js.map +1 -1
- package/dist/navigation/ledger-root-builder.d.ts.map +1 -1
- package/dist/navigation/ledger-root-builder.js +47 -312
- package/dist/navigation/ledger-root-builder.js.map +1 -1
- package/dist/navigation/utils/index.d.ts +0 -1
- package/dist/navigation/utils/index.d.ts.map +1 -1
- package/dist/navigation/utils/index.js +0 -1
- package/dist/navigation/utils/index.js.map +1 -1
- package/dist/orpc-client/docs-ledger/contract.d.ts +0 -9
- package/dist/orpc-client/docs-ledger/contract.d.ts.map +1 -1
- package/dist/orpc-client/docs-ledger/contract.js +0 -1
- package/dist/orpc-client/docs-ledger/contract.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/navigation/ledger-root-builder.d.ts.map +1 -1
- package/dist/types/navigation/utils/index.d.ts +0 -1
- package/dist/types/navigation/utils/index.d.ts.map +1 -1
- package/dist/types/orpc-client/docs-ledger/contract.d.ts +0 -9
- package/dist/types/orpc-client/docs-ledger/contract.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/navigation/__test__/ledger-root-builder.crossProductDedup.test.d.ts +0 -2
- package/dist/navigation/__test__/ledger-root-builder.crossProductDedup.test.d.ts.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.crossProductDedup.test.js +0 -267
- package/dist/navigation/__test__/ledger-root-builder.crossProductDedup.test.js.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.ledgerParity.test.d.ts +0 -2
- package/dist/navigation/__test__/ledger-root-builder.ledgerParity.test.d.ts.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.ledgerParity.test.js +0 -306
- package/dist/navigation/__test__/ledger-root-builder.ledgerParity.test.js.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.sidebarDepth.test.d.ts +0 -2
- package/dist/navigation/__test__/ledger-root-builder.sidebarDepth.test.d.ts.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.sidebarDepth.test.js +0 -273
- package/dist/navigation/__test__/ledger-root-builder.sidebarDepth.test.js.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.d.ts +0 -2
- package/dist/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.d.ts.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.js +0 -234
- package/dist/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.js.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.d.ts +0 -2
- package/dist/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.d.ts.map +0 -1
- package/dist/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.js +0 -360
- package/dist/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.js.map +0 -1
- package/dist/navigation/utils/__test__/syntheticSectionPath.test.d.ts +0 -2
- package/dist/navigation/utils/__test__/syntheticSectionPath.test.d.ts.map +0 -1
- package/dist/navigation/utils/__test__/syntheticSectionPath.test.js +0 -29
- package/dist/navigation/utils/__test__/syntheticSectionPath.test.js.map +0 -1
- package/dist/navigation/utils/syntheticSectionPath.d.ts +0 -13
- package/dist/navigation/utils/syntheticSectionPath.d.ts.map +0 -1
- package/dist/navigation/utils/syntheticSectionPath.js +0 -20
- package/dist/navigation/utils/syntheticSectionPath.js.map +0 -1
- package/dist/types/navigation/__test__/ledger-root-builder.crossProductDedup.test.d.ts +0 -2
- package/dist/types/navigation/__test__/ledger-root-builder.crossProductDedup.test.d.ts.map +0 -1
- package/dist/types/navigation/__test__/ledger-root-builder.ledgerParity.test.d.ts +0 -2
- package/dist/types/navigation/__test__/ledger-root-builder.ledgerParity.test.d.ts.map +0 -1
- package/dist/types/navigation/__test__/ledger-root-builder.sidebarDepth.test.d.ts +0 -2
- package/dist/types/navigation/__test__/ledger-root-builder.sidebarDepth.test.d.ts.map +0 -1
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.d.ts +0 -2
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugGroupOrdering.test.d.ts.map +0 -1
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.d.ts +0 -2
- package/dist/types/navigation/__test__/ledger-root-builder.skipSlugSiblingSection.test.d.ts.map +0 -1
- package/dist/types/navigation/utils/__test__/syntheticSectionPath.test.d.ts +0 -2
- package/dist/types/navigation/utils/__test__/syntheticSectionPath.test.d.ts.map +0 -1
- package/dist/types/navigation/utils/syntheticSectionPath.d.ts +0 -13
- package/dist/types/navigation/utils/syntheticSectionPath.d.ts.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as FernNavigation from "./index.js";
|
|
2
|
-
import { stripSyntheticSegments } from "./utils/syntheticSectionPath.js";
|
|
3
2
|
const STRUCTURAL_SEGMENT_TYPES = new Set([
|
|
4
3
|
"section",
|
|
5
4
|
"apiReference",
|
|
@@ -60,41 +59,6 @@ function metaStr(metadata, key) {
|
|
|
60
59
|
}
|
|
61
60
|
return undefined;
|
|
62
61
|
}
|
|
63
|
-
/**
|
|
64
|
-
* V1 availability values stored in ledger metadata are lowercase (e.g. "deprecated"),
|
|
65
|
-
* but the latest Availability type uses PascalCase (e.g. "Deprecated"). This map
|
|
66
|
-
* normalises both formats so the badge component can look up display names correctly.
|
|
67
|
-
*/
|
|
68
|
-
const AVAILABILITY_LOOKUP = {
|
|
69
|
-
// V1 lowercase values (stored by docsPublishTransform from V1 navigation tree)
|
|
70
|
-
alpha: FernNavigation.Availability.Alpha,
|
|
71
|
-
stable: FernNavigation.Availability.Stable,
|
|
72
|
-
"generally-available": FernNavigation.Availability.GenerallyAvailable,
|
|
73
|
-
"in-development": FernNavigation.Availability.InDevelopment,
|
|
74
|
-
"pre-release": FernNavigation.Availability.PreRelease,
|
|
75
|
-
deprecated: FernNavigation.Availability.Deprecated,
|
|
76
|
-
beta: FernNavigation.Availability.Beta,
|
|
77
|
-
preview: FernNavigation.Availability.Preview,
|
|
78
|
-
legacy: FernNavigation.Availability.Legacy,
|
|
79
|
-
// Latest PascalCase values (pass-through)
|
|
80
|
-
Alpha: FernNavigation.Availability.Alpha,
|
|
81
|
-
Stable: FernNavigation.Availability.Stable,
|
|
82
|
-
GenerallyAvailable: FernNavigation.Availability.GenerallyAvailable,
|
|
83
|
-
InDevelopment: FernNavigation.Availability.InDevelopment,
|
|
84
|
-
PreRelease: FernNavigation.Availability.PreRelease,
|
|
85
|
-
Deprecated: FernNavigation.Availability.Deprecated,
|
|
86
|
-
Beta: FernNavigation.Availability.Beta,
|
|
87
|
-
Preview: FernNavigation.Availability.Preview,
|
|
88
|
-
Legacy: FernNavigation.Availability.Legacy
|
|
89
|
-
};
|
|
90
|
-
/** Read an availability field from metadata, converting V1 lowercase to latest PascalCase. */
|
|
91
|
-
function metaAvailability(metadata) {
|
|
92
|
-
const raw = metaStr(metadata, "availability");
|
|
93
|
-
if (raw == null) {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
return AVAILABILITY_LOOKUP[raw];
|
|
97
|
-
}
|
|
98
62
|
function metaBool(metadata, key) {
|
|
99
63
|
if (metadata != null && typeof metadata === "object" && key in metadata) {
|
|
100
64
|
const v = metadata[key];
|
|
@@ -233,7 +197,7 @@ function artifactToNode(ctx, route) {
|
|
|
233
197
|
}),
|
|
234
198
|
pageId: FernNavigation.PageId(pageId),
|
|
235
199
|
noindex: metaBool(md, "noindex"),
|
|
236
|
-
availability:
|
|
200
|
+
availability: metaStr(md, "availability")
|
|
237
201
|
};
|
|
238
202
|
return node;
|
|
239
203
|
}
|
|
@@ -304,7 +268,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId) {
|
|
|
304
268
|
endpointId: FernNavigation.EndpointId(endpointId),
|
|
305
269
|
apiDefinitionId,
|
|
306
270
|
isResponseStream: metaBool(md, "isResponseStream"),
|
|
307
|
-
availability:
|
|
271
|
+
availability: metaStr(md, "availability"),
|
|
308
272
|
playground: undefined
|
|
309
273
|
};
|
|
310
274
|
}
|
|
@@ -320,7 +284,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId) {
|
|
|
320
284
|
method: method,
|
|
321
285
|
webhookId: FernNavigation.WebhookId(webhookId),
|
|
322
286
|
apiDefinitionId,
|
|
323
|
-
availability:
|
|
287
|
+
availability: metaStr(md, "availability")
|
|
324
288
|
};
|
|
325
289
|
}
|
|
326
290
|
if (route.type === "asyncapi") {
|
|
@@ -333,7 +297,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId) {
|
|
|
333
297
|
...meta,
|
|
334
298
|
webSocketId: FernNavigation.WebSocketId(webSocketId),
|
|
335
299
|
apiDefinitionId,
|
|
336
|
-
availability:
|
|
300
|
+
availability: metaStr(md, "availability"),
|
|
337
301
|
playground: undefined
|
|
338
302
|
};
|
|
339
303
|
}
|
|
@@ -349,7 +313,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId) {
|
|
|
349
313
|
method: method,
|
|
350
314
|
grpcId: FernNavigation.GrpcId(grpcId),
|
|
351
315
|
apiDefinitionId,
|
|
352
|
-
availability:
|
|
316
|
+
availability: metaStr(md, "availability")
|
|
353
317
|
};
|
|
354
318
|
}
|
|
355
319
|
if (route.type === "graphql") {
|
|
@@ -365,7 +329,7 @@ function apiLeafNodeFromNavRouteInternal(ctx, route, segmentApiDefinitionId) {
|
|
|
365
329
|
graphqlOperationId: FernNavigation.GraphQlOperationId(graphqlOperationId),
|
|
366
330
|
graphqlOperationIds: undefined,
|
|
367
331
|
apiDefinitionId,
|
|
368
|
-
availability:
|
|
332
|
+
availability: metaStr(md, "availability"),
|
|
369
333
|
playground: undefined
|
|
370
334
|
};
|
|
371
335
|
}
|
|
@@ -553,8 +517,7 @@ function structuralNodeSlug(ctx, overviewFullPath, section, scopePrefix) {
|
|
|
553
517
|
// basepath-absolute (it is the version/product/tab node's slug), so join it
|
|
554
518
|
// directly rather than going through `contentSlug` (which would re-prefix
|
|
555
519
|
// the basepath).
|
|
556
|
-
|
|
557
|
-
return cleanSection !== "" ? FernNavigation.slugjoin(scopePrefix, cleanSection) : scopePrefix;
|
|
520
|
+
return section !== "" ? FernNavigation.slugjoin(scopePrefix, section) : scopePrefix;
|
|
558
521
|
}
|
|
559
522
|
function stripLeadingScopePrefix(section, scopePrefix) {
|
|
560
523
|
const prefix = scopePrefix;
|
|
@@ -569,30 +532,6 @@ function stripLeadingScopePrefix(section, scopePrefix) {
|
|
|
569
532
|
}
|
|
570
533
|
return section;
|
|
571
534
|
}
|
|
572
|
-
function computeDuplicateSiblingSortBoundaries(siblings) {
|
|
573
|
-
const result = new Map();
|
|
574
|
-
const byPath = new Map();
|
|
575
|
-
for (const sibling of siblings) {
|
|
576
|
-
if (metaStr(sibling.seg.metadata, "type") !== "section") {
|
|
577
|
-
continue;
|
|
578
|
-
}
|
|
579
|
-
const group = byPath.get(sibling.seg.section) ?? [];
|
|
580
|
-
group.push(sibling);
|
|
581
|
-
byPath.set(sibling.seg.section, group);
|
|
582
|
-
}
|
|
583
|
-
for (const [, group] of byPath) {
|
|
584
|
-
if (group.length <= 1) {
|
|
585
|
-
continue;
|
|
586
|
-
}
|
|
587
|
-
for (let i = 0; i < group.length; i++) {
|
|
588
|
-
result.set(group[i], {
|
|
589
|
-
lo: group[i].seg.sortOrder,
|
|
590
|
-
hi: i + 1 < group.length ? group[i + 1].seg.sortOrder : Number.MAX_SAFE_INTEGER
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
return result;
|
|
595
|
-
}
|
|
596
535
|
/**
|
|
597
536
|
* Merge leaf children and section children by their original V1 tree position.
|
|
598
537
|
* Leaves carry position via `displaySortOrder` (stored in nav routes), sections
|
|
@@ -656,7 +595,7 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
|
|
|
656
595
|
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
657
596
|
collapsible: metaBool(seg.metadata, "collapsible") ?? (metaCollapsed(seg.metadata) === true ? true : undefined),
|
|
658
597
|
collapsedByDefault: metaBool(seg.metadata, "collapsedByDefault") ?? (metaCollapsed(seg.metadata) === true ? true : undefined),
|
|
659
|
-
availability:
|
|
598
|
+
availability: metaStr(seg.metadata, "availability"),
|
|
660
599
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : undefined,
|
|
661
600
|
children: mergeChildrenByPosition(ctx, nav, sectionChildren)
|
|
662
601
|
};
|
|
@@ -666,16 +605,13 @@ function sectionNode(ctx, scoped, sectionChildren, scopePrefix) {
|
|
|
666
605
|
* `parentSectionPath(seg.section) === parentSection`, or is an orphaned segment
|
|
667
606
|
* whose nearest existing ancestor is `parentSection`.
|
|
668
607
|
*/
|
|
669
|
-
function directChildApiPackages(parentSection, scopeSegs
|
|
608
|
+
function directChildApiPackages(parentSection, scopeSegs) {
|
|
670
609
|
const sectionPaths = new Set(scopeSegs.map((s) => s.seg.section));
|
|
671
610
|
return scopeSegs
|
|
672
611
|
.filter((s) => {
|
|
673
612
|
if (metaStr(s.seg.metadata, "type") !== "apiPackage") {
|
|
674
613
|
return false;
|
|
675
614
|
}
|
|
676
|
-
if (metaStr(s.seg.metadata, "apiDefinitionId") !== apiDefinitionId) {
|
|
677
|
-
return false;
|
|
678
|
-
}
|
|
679
615
|
const parent = parentSectionPath(s.seg.section);
|
|
680
616
|
if (parent === parentSection) {
|
|
681
617
|
return true;
|
|
@@ -700,37 +636,11 @@ function buildApiChildren(ctx, scoped, scopeSegs, apiDefinitionId, scopePrefix)
|
|
|
700
636
|
// API leaf types.
|
|
701
637
|
const leafNodes = positionedApiLeafChildren(ctx, nav, apiDefinitionId);
|
|
702
638
|
// Build nested ApiPackageNodes from direct child apiPackage segments.
|
|
703
|
-
|
|
704
|
-
// When multiple API-type segments share the same section path (skipUrlSlug
|
|
705
|
-
// group packages that collapse to their parent's section), children from
|
|
706
|
-
// different groups get mixed together. Scope children to this segment's DFS
|
|
707
|
-
// subtree using sortOrder boundaries to restore correct ownership.
|
|
708
|
-
const samePathApiSiblings = scopeSegs.filter((s) => s.seg.section === seg.section &&
|
|
709
|
-
s.seg.sortOrder !== seg.sortOrder &&
|
|
710
|
-
API_NODE_SEGMENT_TYPES.has(metaStr(s.seg.metadata, "type") ?? ""));
|
|
711
|
-
const hasCollapsedGroups = samePathApiSiblings.length > 0;
|
|
712
|
-
if (hasCollapsedGroups && metaStr(seg.metadata, "type") !== "apiReference") {
|
|
713
|
-
// This is a group package sharing its section with siblings.
|
|
714
|
-
// Only claim children whose sortOrder falls within our DFS subtree.
|
|
715
|
-
const nextSibling = samePathApiSiblings
|
|
716
|
-
.filter((s) => s.seg.sortOrder > seg.sortOrder)
|
|
717
|
-
.sort((a, b) => a.seg.sortOrder - b.seg.sortOrder)[0];
|
|
718
|
-
const lo = seg.sortOrder;
|
|
719
|
-
const hi = nextSibling?.seg.sortOrder ?? Number.MAX_SAFE_INTEGER;
|
|
720
|
-
childPackages = childPackages.filter((c) => c.seg.sortOrder > lo && c.seg.sortOrder < hi);
|
|
721
|
-
}
|
|
639
|
+
const childPackages = directChildApiPackages(seg.section, scopeSegs);
|
|
722
640
|
const packageNodes = childPackages.map((child) => ({
|
|
723
641
|
node: apiPackageChildNode(ctx, child, scopeSegs, apiDefinitionId, scopePrefix),
|
|
724
642
|
childIndex: metaNum(child.seg.metadata, "childIndex")
|
|
725
643
|
}));
|
|
726
|
-
// When collapsed groups are detected at apiReference level, children's
|
|
727
|
-
// childIndex values are relative to different parent groups and cannot be
|
|
728
|
-
// used for interleaving. Fall back to sortOrder (DFS creation order).
|
|
729
|
-
if (hasCollapsedGroups && metaStr(seg.metadata, "type") === "apiReference") {
|
|
730
|
-
return [...leafNodes, ...packageNodes.map((p, i) => ({ node: p.node, pos: leafNodes.length + i }))]
|
|
731
|
-
.sort((a, b) => a.pos - b.pos)
|
|
732
|
-
.map((p) => p.node);
|
|
733
|
-
}
|
|
734
644
|
// Interleave by position when childIndex metadata is available
|
|
735
645
|
const hasChildIndex = packageNodes.some((p) => p.childIndex != null);
|
|
736
646
|
if (!hasChildIndex) {
|
|
@@ -774,7 +684,7 @@ function apiPackageChildNode(ctx, scoped, scopeSegs, parentApiDefinitionId, scop
|
|
|
774
684
|
featureFlags: metaFeatureFlags(seg.metadata)
|
|
775
685
|
}),
|
|
776
686
|
apiDefinitionId: FernNavigation.ApiDefinitionId(apiDefinitionId),
|
|
777
|
-
availability:
|
|
687
|
+
availability: metaStr(seg.metadata, "availability"),
|
|
778
688
|
overviewPageId: overviewPageId != null ? FernNavigation.PageId(overviewPageId) : undefined,
|
|
779
689
|
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
780
690
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : undefined,
|
|
@@ -884,10 +794,10 @@ function apiReferenceNode(ctx, scoped, scopeSegs, scopePrefix) {
|
|
|
884
794
|
featureFlags: metaFeatureFlags(seg.metadata)
|
|
885
795
|
}),
|
|
886
796
|
apiDefinitionId: FernNavigation.ApiDefinitionId(apiDefinitionId),
|
|
887
|
-
availability:
|
|
797
|
+
availability: metaStr(seg.metadata, "availability"),
|
|
888
798
|
overviewPageId: overviewPageId != null ? FernNavigation.PageId(overviewPageId) : undefined,
|
|
889
799
|
noindex: metaBool(overview?.metadata, "noindex") ?? metaBool(seg.metadata, "noindex"),
|
|
890
|
-
paginated:
|
|
800
|
+
paginated: true,
|
|
891
801
|
showErrors: metaBool(seg.metadata, "showErrors"),
|
|
892
802
|
hideTitle: metaBool(seg.metadata, "hideTitle"),
|
|
893
803
|
pointsTo: metaPointsTo != null ? pointsToSlug(metaPointsTo) : undefined,
|
|
@@ -905,12 +815,7 @@ function attachedApiChangelogNode(ctx, scoped, scopeSegs, apiDefinitionId, scope
|
|
|
905
815
|
}
|
|
906
816
|
return metaStr(candidate.seg.metadata, "apiDefinitionId") === apiDefinitionId;
|
|
907
817
|
});
|
|
908
|
-
const
|
|
909
|
-
return (metaStr(candidate.seg.metadata, "type") === "apiReference" &&
|
|
910
|
-
metaStr(candidate.seg.metadata, "apiDefinitionId") === apiDefinitionId);
|
|
911
|
-
}).length;
|
|
912
|
-
const changelogSeg = candidates.find((candidate) => parentSectionPath(candidate.seg.section) === seg.section) ??
|
|
913
|
-
(apiReferenceCount === 1 ? candidates[0] : undefined);
|
|
818
|
+
const changelogSeg = candidates.find((candidate) => parentSectionPath(candidate.seg.section) === seg.section) ?? candidates[0];
|
|
914
819
|
return changelogSeg != null ? changelogNode(ctx, changelogSeg, scopePrefix) : undefined;
|
|
915
820
|
}
|
|
916
821
|
function hasOwningApiReference(scoped, scopeSegs) {
|
|
@@ -918,68 +823,12 @@ function hasOwningApiReference(scoped, scopeSegs) {
|
|
|
918
823
|
if (apiDefinitionId == null || metaStr(scoped.seg.metadata, "type") !== "changelog") {
|
|
919
824
|
return false;
|
|
920
825
|
}
|
|
921
|
-
|
|
826
|
+
return scopeSegs.some((candidate) => {
|
|
922
827
|
if (metaStr(candidate.seg.metadata, "type") !== "apiReference") {
|
|
923
828
|
return false;
|
|
924
829
|
}
|
|
925
830
|
return metaStr(candidate.seg.metadata, "apiDefinitionId") === apiDefinitionId;
|
|
926
831
|
});
|
|
927
|
-
return (candidates.some((candidate) => parentSectionPath(scoped.seg.section) === candidate.seg.section) ||
|
|
928
|
-
candidates.length === 1);
|
|
929
|
-
}
|
|
930
|
-
/**
|
|
931
|
-
* True when this segment is an `apiPackage` that will be nested under an in-scope
|
|
932
|
-
* `apiReference` for the same API by {@link buildApiChildren}, and therefore must
|
|
933
|
-
* NOT also be emitted as a standalone root/section node.
|
|
934
|
-
*
|
|
935
|
-
* Without this guard, a skip-slug apiReference (section "") leaves its resource
|
|
936
|
-
* subpackages with `parentSectionPath === ""`, so they look root-level and get
|
|
937
|
-
* emitted a second time as always-expanded top-level apiReference nodes —
|
|
938
|
-
* duplicating every resource and endpoint in the sidebar (the "67 apiReference
|
|
939
|
-
* nodes vs 1" API-reference regression).
|
|
940
|
-
*
|
|
941
|
-
* Reachability mirrors {@link directChildApiPackages}: walk up the section-path
|
|
942
|
-
* chain (hopping to nearestExistingAncestor when a parent section is absent)
|
|
943
|
-
* until we reach an apiReference's section. If no apiReference is an ancestor the
|
|
944
|
-
* package is left where it is, so it can never be dropped.
|
|
945
|
-
*/
|
|
946
|
-
function isNestedApiPackage(scoped, scopeSegs) {
|
|
947
|
-
if (metaStr(scoped.seg.metadata, "type") !== "apiPackage") {
|
|
948
|
-
return false;
|
|
949
|
-
}
|
|
950
|
-
const apiDefinitionId = metaStr(scoped.seg.metadata, "apiDefinitionId");
|
|
951
|
-
if (apiDefinitionId == null) {
|
|
952
|
-
return false;
|
|
953
|
-
}
|
|
954
|
-
const apiReferenceSections = new Set(scopeSegs
|
|
955
|
-
.filter((s) => metaStr(s.seg.metadata, "type") === "apiReference" &&
|
|
956
|
-
metaStr(s.seg.metadata, "apiDefinitionId") === apiDefinitionId)
|
|
957
|
-
.map((s) => s.seg.section));
|
|
958
|
-
if (apiReferenceSections.size === 0) {
|
|
959
|
-
return false;
|
|
960
|
-
}
|
|
961
|
-
const sectionPaths = new Set(scopeSegs.map((s) => s.seg.section));
|
|
962
|
-
const resolveParent = (section) => {
|
|
963
|
-
const parent = parentSectionPath(section);
|
|
964
|
-
if (parent === "" || sectionPaths.has(parent)) {
|
|
965
|
-
return parent;
|
|
966
|
-
}
|
|
967
|
-
return nearestExistingAncestor(section, sectionPaths);
|
|
968
|
-
};
|
|
969
|
-
let current = scoped.seg.section;
|
|
970
|
-
const seen = new Set([current]);
|
|
971
|
-
// Walk up until we hit an owning apiReference (nested → true) or run out.
|
|
972
|
-
for (;;) {
|
|
973
|
-
const parent = resolveParent(current);
|
|
974
|
-
if (apiReferenceSections.has(parent)) {
|
|
975
|
-
return true;
|
|
976
|
-
}
|
|
977
|
-
if (parent === "" || seen.has(parent)) {
|
|
978
|
-
return false;
|
|
979
|
-
}
|
|
980
|
-
seen.add(parent);
|
|
981
|
-
current = parent;
|
|
982
|
-
}
|
|
983
832
|
}
|
|
984
833
|
function changelogNode(ctx, scoped, scopePrefix) {
|
|
985
834
|
const { seg, nav } = scoped;
|
|
@@ -1103,13 +952,7 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
|
|
|
1103
952
|
if (sec === "" || type === "tabRoot") {
|
|
1104
953
|
return false;
|
|
1105
954
|
}
|
|
1106
|
-
if (hasOwningApiReference(s, scopeSegs)
|
|
1107
|
-
return false;
|
|
1108
|
-
}
|
|
1109
|
-
// Segments marked as sidebar depth 0 are V1 root-level peers and
|
|
1110
|
-
// must never be adopted as children of another section.
|
|
1111
|
-
const depth = metaNum(s.seg.metadata, "sidebarDepth");
|
|
1112
|
-
if (depth === 0) {
|
|
955
|
+
if (hasOwningApiReference(s, scopeSegs)) {
|
|
1113
956
|
return false;
|
|
1114
957
|
}
|
|
1115
958
|
const parent = parentSectionPath(sec);
|
|
@@ -1124,7 +967,6 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
|
|
|
1124
967
|
return false;
|
|
1125
968
|
})
|
|
1126
969
|
.sort((a, b) => a.seg.sortOrder - b.seg.sortOrder);
|
|
1127
|
-
const siblingBoundaries = computeDuplicateSiblingSortBoundaries(direct);
|
|
1128
970
|
return direct.map((s) => {
|
|
1129
971
|
const type = metaStr(s.seg.metadata, "type");
|
|
1130
972
|
const childIndex = metaNum(s.seg.metadata, "childIndex");
|
|
@@ -1137,11 +979,7 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
|
|
|
1137
979
|
}
|
|
1138
980
|
else {
|
|
1139
981
|
// section (or unrecognised) → recurse for nested sections.
|
|
1140
|
-
|
|
1141
|
-
const childScopeSegs = boundary != null
|
|
1142
|
-
? scopeSegs.filter((candidate) => candidate.seg.sortOrder >= boundary.lo && candidate.seg.sortOrder < boundary.hi)
|
|
1143
|
-
: scopeSegs;
|
|
1144
|
-
node = sectionNode(ctx, s, buildSectionTree(ctx, childScopeSegs, s.seg.section, scopePrefix, changelogScopePrefix), scopePrefix);
|
|
982
|
+
node = sectionNode(ctx, s, buildSectionTree(ctx, scopeSegs, s.seg.section, scopePrefix, changelogScopePrefix), scopePrefix);
|
|
1145
983
|
}
|
|
1146
984
|
return { node, childIndex };
|
|
1147
985
|
});
|
|
@@ -1161,26 +999,16 @@ function buildSectionTree(ctx, scopeSegs, parentPath, scopePrefix, changelogScop
|
|
|
1161
999
|
function computeSiblingSortBoundaries(ordered) {
|
|
1162
1000
|
const result = new Map();
|
|
1163
1001
|
// Collect root-level sections grouped by their section path.
|
|
1164
|
-
// Sections with sec==="" (skip-slug sections) are included: when multiple
|
|
1165
|
-
// skip-slug sections exist at the root, they share path "" and need
|
|
1166
|
-
// boundaries so each only adopts its own children.
|
|
1167
1002
|
const sectionPaths = new Set(ordered.map((s) => s.seg.section));
|
|
1168
1003
|
const rootSections = [];
|
|
1169
1004
|
for (const s of ordered) {
|
|
1170
1005
|
const type = metaStr(s.seg.metadata, "type");
|
|
1171
1006
|
const sec = s.seg.section;
|
|
1172
|
-
if (type !== "section") {
|
|
1173
|
-
continue;
|
|
1174
|
-
}
|
|
1175
|
-
if (sec === "") {
|
|
1176
|
-
rootSections.push(s);
|
|
1007
|
+
if (type !== "section" || sec === "") {
|
|
1177
1008
|
continue;
|
|
1178
1009
|
}
|
|
1179
|
-
const depth = metaNum(s.seg.metadata, "sidebarDepth");
|
|
1180
1010
|
const parent = parentSectionPath(sec);
|
|
1181
|
-
const isRootLevel =
|
|
1182
|
-
parent === "" ||
|
|
1183
|
-
(!sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "");
|
|
1011
|
+
const isRootLevel = parent === "" || (!sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "");
|
|
1184
1012
|
if (isRootLevel) {
|
|
1185
1013
|
rootSections.push(s);
|
|
1186
1014
|
}
|
|
@@ -1225,17 +1053,6 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
|
|
|
1225
1053
|
// segments. Both index into the SAME child list at write time, so they
|
|
1226
1054
|
// interleave directly (e.g. [page 0, page 1, section 2…15, page 16, 17]).
|
|
1227
1055
|
const annotated = [];
|
|
1228
|
-
// ── Sibling section ownership ────────────────────────────────────────
|
|
1229
|
-
//
|
|
1230
|
-
// Multiple root-level sections can share the same section path (e.g.
|
|
1231
|
-
// three sections all with path equal to the version slug). When this
|
|
1232
|
-
// happens, buildSectionTree would incorrectly give ALL child subsections
|
|
1233
|
-
// to each sibling. We resolve ownership via sortOrder: a section owns
|
|
1234
|
-
// segments whose sortOrder falls between its own and the next sibling's.
|
|
1235
|
-
//
|
|
1236
|
-
// Computed first because hasRootSection (below) uses it to decide
|
|
1237
|
-
// whether bounded skip-slug siblings should activate adoption.
|
|
1238
|
-
const siblingBoundaries = computeSiblingSortBoundaries(ordered);
|
|
1239
1056
|
// ── Root-section adoption flow ──────────────────────────────────────
|
|
1240
1057
|
//
|
|
1241
1058
|
// A scope may contain a "root section" — a segment with type "section"
|
|
@@ -1247,42 +1064,28 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
|
|
|
1247
1064
|
// │ → emit pages/links inline at their displaySortOrder
|
|
1248
1065
|
// │
|
|
1249
1066
|
// ├─ (B) the root section itself (sec=="", type=="section")
|
|
1250
|
-
// │ → buildSectionTree adopts
|
|
1251
|
-
// │ → emit one sectionNode wrapping the subtree
|
|
1067
|
+
// │ → buildSectionTree adopts ALL depth-0 children as its own
|
|
1068
|
+
// │ → emit one sectionNode wrapping the whole subtree
|
|
1252
1069
|
// │
|
|
1253
|
-
// └─ (C) depth-0 sections (
|
|
1254
|
-
// →
|
|
1070
|
+
// └─ (C) depth-0 sections (parentSectionPath=="")
|
|
1071
|
+
// → SKIP — already adopted by (B) via buildSectionTree
|
|
1255
1072
|
//
|
|
1256
1073
|
// Without a root section, depth-0 sections are emitted directly.
|
|
1074
|
+
const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" && s.seg.section === "");
|
|
1075
|
+
// ── Sibling section ownership ────────────────────────────────────────
|
|
1257
1076
|
//
|
|
1258
|
-
//
|
|
1259
|
-
//
|
|
1260
|
-
//
|
|
1261
|
-
//
|
|
1262
|
-
//
|
|
1263
|
-
|
|
1264
|
-
// boundaries (multiple sec="" sections sharing the same path), which
|
|
1265
|
-
// correctly scope each section's children. A *single* unbounded
|
|
1266
|
-
// skip-slug sibling (e.g. mangopay's "Introduction") must NOT adopt
|
|
1267
|
-
// its depth-0 peers — doing so produces spurious breadcrumb entries.
|
|
1268
|
-
const hasRootSection = ordered.some((s) => metaStr(s.seg.metadata, "type") === "section" &&
|
|
1269
|
-
s.seg.section === "" &&
|
|
1270
|
-
(metaNum(s.seg.metadata, "childIndex") == null || siblingBoundaries.has(s)));
|
|
1077
|
+
// Multiple root-level sections can share the same section path (e.g.
|
|
1078
|
+
// three sections all with path equal to the version slug). When this
|
|
1079
|
+
// happens, buildSectionTree would incorrectly give ALL child subsections
|
|
1080
|
+
// to each sibling. We resolve ownership via sortOrder: a section owns
|
|
1081
|
+
// segments whose sortOrder falls between its own and the next sibling's.
|
|
1082
|
+
const siblingBoundaries = computeSiblingSortBoundaries(ordered);
|
|
1271
1083
|
for (const s of ordered) {
|
|
1272
1084
|
const type = metaStr(s.seg.metadata, "type");
|
|
1273
1085
|
const sec = s.seg.section;
|
|
1274
|
-
if (hasOwningApiReference(s, scopeSegs)
|
|
1086
|
+
if (hasOwningApiReference(s, scopeSegs)) {
|
|
1275
1087
|
continue;
|
|
1276
1088
|
}
|
|
1277
|
-
// Skip apiPackage segments that share their section path with an
|
|
1278
|
-
// apiReference sibling (skipUrlSlug structural wrappers). Their
|
|
1279
|
-
// children are already claimed by the apiReference via DFS ordering.
|
|
1280
|
-
if (type === "apiPackage") {
|
|
1281
|
-
const hasApiRefSibling = ordered.some((sib) => sib.seg.section === sec && metaStr(sib.seg.metadata, "type") === "apiReference");
|
|
1282
|
-
if (hasApiRefSibling) {
|
|
1283
|
-
continue;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
1089
|
if (type === "tabRoot" && metaBool(s.seg.metadata, "landingPage") === true) {
|
|
1287
1090
|
continue;
|
|
1288
1091
|
}
|
|
@@ -1299,35 +1102,21 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
|
|
|
1299
1102
|
continue;
|
|
1300
1103
|
}
|
|
1301
1104
|
// (B) Root section wrapper — adopts depth-0 children via buildSectionTree.
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
// When multiple sections share sec==="" (skip-slug), scope children
|
|
1305
|
-
// to each section's sortOrder range so subsections aren't duplicated.
|
|
1306
|
-
if (type === "section" && sec === "" && hasRootSection) {
|
|
1307
|
-
const bounds = siblingBoundaries.get(s);
|
|
1308
|
-
const ownedSegs = bounds != null
|
|
1309
|
-
? scopeSegs.filter((seg) => seg.seg.sortOrder >= bounds.lo && seg.seg.sortOrder < bounds.hi)
|
|
1310
|
-
: scopeSegs;
|
|
1311
|
-
const sectionChildren = buildSectionTree(ctx, ownedSegs, "", scopePrefix, changelogScopePrefix);
|
|
1105
|
+
if (type === "section" && sec === "") {
|
|
1106
|
+
const sectionChildren = buildSectionTree(ctx, scopeSegs, "", scopePrefix);
|
|
1312
1107
|
const node = sectionNode(ctx, s, sectionChildren, scopePrefix);
|
|
1313
1108
|
annotated.push({ node, pos: metaNum(s.seg.metadata, "childIndex"), isLeaf: false });
|
|
1314
1109
|
continue;
|
|
1315
1110
|
}
|
|
1316
1111
|
// (C) Depth-0 or orphaned sections — emit at root unless already
|
|
1317
1112
|
// adopted by a root section (B).
|
|
1318
|
-
const depth = metaNum(s.seg.metadata, "sidebarDepth");
|
|
1319
1113
|
const parent = parentSectionPath(sec);
|
|
1320
|
-
const isRootLevel =
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
//
|
|
1324
|
-
//
|
|
1325
|
-
|
|
1326
|
-
// Sections with sidebarDepth>0 are nested children that SHOULD
|
|
1327
|
-
// be adopted, so they must be skipped to avoid duplication.
|
|
1328
|
-
// Sections without sidebarDepth (old data) are also skipped —
|
|
1329
|
-
// they rely on path-based hierarchy in buildSectionTree.
|
|
1330
|
-
if (isRootLevel && hasRootSection && sec !== "" && depth !== 0) {
|
|
1114
|
+
const isRootLevel = parent === "" || (!sectionPaths.has(parent) && nearestExistingAncestor(sec, sectionPaths) === "");
|
|
1115
|
+
// Skip depth-0 sections already adopted by the root section wrapper (B),
|
|
1116
|
+
// but NOT structural types with sec="" (skip-slug). buildSectionTree
|
|
1117
|
+
// filters out sec="" segments (line 1249), so they wouldn't be adopted
|
|
1118
|
+
// and must be emitted here directly.
|
|
1119
|
+
if (isRootLevel && hasRootSection && sec !== "") {
|
|
1331
1120
|
continue;
|
|
1332
1121
|
}
|
|
1333
1122
|
if (isRootLevel) {
|
|
@@ -1345,20 +1134,7 @@ function buildSidebarRootChildren(ctx, scopeSegs, scopePrefix, changelogScopePre
|
|
|
1345
1134
|
const ownedSegs = bounds != null
|
|
1346
1135
|
? scopeSegs.filter((seg) => seg.seg.sortOrder >= bounds.lo && seg.seg.sortOrder < bounds.hi)
|
|
1347
1136
|
: scopeSegs;
|
|
1348
|
-
|
|
1349
|
-
// root wrapper in case B) is a skipUrlSlug sibling.
|
|
1350
|
-
// When sortOrder boundaries exist (multiple sec="" sections),
|
|
1351
|
-
// the scoped ownedSegs correctly limits which subsections
|
|
1352
|
-
// each section can adopt. When there are NO boundaries
|
|
1353
|
-
// (single sec="" section, e.g. mangopay's "Introduction"),
|
|
1354
|
-
// buildSectionTree("") would re-adopt all depth-0 peers;
|
|
1355
|
-
// pass an empty child list instead — its leaf artifacts are
|
|
1356
|
-
// already in its own segment nav.
|
|
1357
|
-
const isUnboundedSkipSlugSibling = sec === "" && metaNum(s.seg.metadata, "childIndex") != null && bounds == null;
|
|
1358
|
-
const sectionChildren = isUnboundedSkipSlugSibling
|
|
1359
|
-
? []
|
|
1360
|
-
: buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix);
|
|
1361
|
-
node = sectionNode(ctx, s, sectionChildren, scopePrefix);
|
|
1137
|
+
node = sectionNode(ctx, s, buildSectionTree(ctx, ownedSegs, sec, scopePrefix, changelogScopePrefix), scopePrefix);
|
|
1362
1138
|
}
|
|
1363
1139
|
// Shared/merged sections (paths not rooted in scopePrefix) must not
|
|
1364
1140
|
// carry childIndex — their source-version positions would sort them
|
|
@@ -1428,6 +1204,11 @@ function groupSidebarRootChildren(ctx, children) {
|
|
|
1428
1204
|
flushRun();
|
|
1429
1205
|
out.push(child);
|
|
1430
1206
|
}
|
|
1207
|
+
else if (child.type === "changelog") {
|
|
1208
|
+
flushRun();
|
|
1209
|
+
run.push(child);
|
|
1210
|
+
flushRun();
|
|
1211
|
+
}
|
|
1431
1212
|
else {
|
|
1432
1213
|
run.push(child);
|
|
1433
1214
|
}
|
|
@@ -1594,7 +1375,7 @@ function buildVariantedNode(ctx, variants, scopeSegs, scopePrefix) {
|
|
|
1594
1375
|
? asSlug(FernNavigation.slugjoin(scopePrefix, variantIndividualSlug))
|
|
1595
1376
|
: scopePrefix;
|
|
1596
1377
|
const metaPointsTo = metaStr(variant.metadata, "pointsTo");
|
|
1597
|
-
const children = buildSidebarRootChildren(ctx, variantSegs,
|
|
1378
|
+
const children = buildSidebarRootChildren(ctx, variantSegs, scopePrefix);
|
|
1598
1379
|
return {
|
|
1599
1380
|
type: "variant",
|
|
1600
1381
|
...withMetadataDefaults({
|
|
@@ -2130,14 +1911,6 @@ function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMer
|
|
|
2130
1911
|
};
|
|
2131
1912
|
return node;
|
|
2132
1913
|
});
|
|
2133
|
-
// Cross-product canonical slug deduplication (V2 parity).
|
|
2134
|
-
// V2's migrator deduplicates pages across products via a global pageId map:
|
|
2135
|
-
// the first product to register a pageId wins, and subsequent products'
|
|
2136
|
-
// pages with the same pageId receive a canonicalSlug pointing to the
|
|
2137
|
-
// canonical (default-product) page. Without this, shared content that is
|
|
2138
|
-
// materialized under every product scope (e.g. merge-api-basics pages)
|
|
2139
|
-
// appears as separate sitemap entries per product.
|
|
2140
|
-
markCrossProductCanonicalSlugs(children);
|
|
2141
1914
|
return {
|
|
2142
1915
|
type: "productgroup",
|
|
2143
1916
|
id: ctx.nodeId("productgroup"),
|
|
@@ -2146,43 +1919,5 @@ function buildProductGroup(ctx, products, scoped, rootSlug, skipSharedSectionMer
|
|
|
2146
1919
|
children
|
|
2147
1920
|
};
|
|
2148
1921
|
}
|
|
2149
|
-
/**
|
|
2150
|
-
* Deduplicate pages across products using pageId as a content-identity key.
|
|
2151
|
-
* Pages with the same pageId in different products are the same content
|
|
2152
|
-
* materialized per-scope; the default product's slug becomes canonical and
|
|
2153
|
-
* non-default copies receive `canonicalSlug` so the sitemap collapses them.
|
|
2154
|
-
*
|
|
2155
|
-
* API leaf nodes (endpoints, websockets, etc.) are unaffected — `getPageId`
|
|
2156
|
-
* returns undefined for those types, so product-specific API surface is
|
|
2157
|
-
* never suppressed.
|
|
2158
|
-
*/
|
|
2159
|
-
function markCrossProductCanonicalSlugs(productNodes) {
|
|
2160
|
-
const pageIdToCanonical = new Map();
|
|
2161
|
-
// Process default product first so its slugs become the canonical targets.
|
|
2162
|
-
const sorted = [...productNodes].sort((a, b) => {
|
|
2163
|
-
if (a.default !== b.default) {
|
|
2164
|
-
return a.default ? -1 : 1;
|
|
2165
|
-
}
|
|
2166
|
-
return 0;
|
|
2167
|
-
});
|
|
2168
|
-
for (const product of sorted) {
|
|
2169
|
-
FernNavigation.traverseDF(product, (child) => {
|
|
2170
|
-
if (FernNavigation.hasMetadata(child) && FernNavigation.isPage(child)) {
|
|
2171
|
-
const pid = FernNavigation.getPageId(child);
|
|
2172
|
-
if (pid == null) {
|
|
2173
|
-
return;
|
|
2174
|
-
}
|
|
2175
|
-
const key = `pid:${pid}`;
|
|
2176
|
-
const canonical = pageIdToCanonical.get(key);
|
|
2177
|
-
if (canonical != null && !product.default) {
|
|
2178
|
-
child.canonicalSlug = canonical;
|
|
2179
|
-
}
|
|
2180
|
-
else if (canonical == null) {
|
|
2181
|
-
pageIdToCanonical.set(key, child.canonicalSlug ?? child.slug);
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
});
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
1922
|
// (root keeps the bare "root" id; it is the single tree root.)
|
|
2188
1923
|
//# sourceMappingURL=ledger-root-builder.js.map
|