diff --git a/servers/fdr/src/controllers/docs/v1/getDocsReadService.ts b/servers/fdr/src/controllers/docs/v1/getDocsReadService.ts index 2ab908e46f..58880bb2b7 100644 --- a/servers/fdr/src/controllers/docs/v1/getDocsReadService.ts +++ b/servers/fdr/src/controllers/docs/v1/getDocsReadService.ts @@ -5,6 +5,7 @@ import { DocsV1Db, DocsV1Read, FdrAPI, + FernNavigation, convertDbAPIDefinitionToRead, convertDocsDefinitionToRead, migrateDocsDbDefinition, @@ -171,6 +172,56 @@ export async function loadIndexSegmentsAndGetSearchInfo({ }); } +function getVersionedSearchInfoFromDocs(activeIndexSegments: IndexSegment[], app: FdrApplication): Algolia.SearchInfo { + const indexSegmentsByVersionId = activeIndexSegments.reduce>( + (acc, indexSegment) => { + const searchApiKey = app.services.algoliaIndexSegmentManager.getOrGenerateSearchApiKeyForIndexSegment( + indexSegment.id, + ); + // Since the docs are versioned, all referenced index segments will have a version + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + acc[indexSegment.version!] = { + id: FdrAPI.IndexSegmentId(indexSegment.id), + searchApiKey, + }; + return acc; + }, + {}, + ); + return { + type: "singleAlgoliaIndex", + value: { + type: "versioned", + indexSegmentsByVersionId, + }, + }; +} + +function getUnversionedSearchInfoFromDocs( + activeIndexSegments: IndexSegment[], + app: FdrApplication, +): Algolia.SearchInfo { + const indexSegment = activeIndexSegments[0]; + if (indexSegment == null) { + /* preview docs do not have algolia index segments, and should return with an undefined index */ + return { type: "legacyMultiAlgoliaIndex", algoliaIndex: undefined }; + } + const searchApiKey = app.services.algoliaIndexSegmentManager.getOrGenerateSearchApiKeyForIndexSegment( + indexSegment.id, + ); + + return { + type: "singleAlgoliaIndex", + value: { + type: "unversioned", + indexSegment: { + id: FdrAPI.IndexSegmentId(indexSegment.id), + searchApiKey, + }, + }, + }; +} + export function getSearchInfoFromDocs({ algoliaIndex, indexSegmentIds, @@ -184,57 +235,42 @@ export function getSearchInfoFromDocs({ docsDbDefinition: DocsV1Db.DocsDefinitionDb; app: FdrApplication; }): Algolia.SearchInfo { - if (indexSegmentIds == null || docsDbDefinition.config.navigation == null) { + if (indexSegmentIds == null) { return { type: "legacyMultiAlgoliaIndex", algoliaIndex }; } - return visitDbNavigationConfig(docsDbDefinition.config.navigation, { - versioned: () => { - const indexSegmentsByVersionId = activeIndexSegments.reduce>( - (acc, indexSegment) => { - const searchApiKey = - app.services.algoliaIndexSegmentManager.getOrGenerateSearchApiKeyForIndexSegment( - indexSegment.id, - ); - // Since the docs are versioned, all referenced index segments will have a version - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - acc[indexSegment.version!] = { - id: FdrAPI.IndexSegmentId(indexSegment.id), - searchApiKey, - }; - return acc; - }, - {}, - ); - return { - type: "singleAlgoliaIndex", - value: { - type: "versioned", - indexSegmentsByVersionId, - }, - }; - }, - unversioned: () => { - const indexSegment = activeIndexSegments[0]; - if (indexSegment == null) { - /* preview docs do not have algolia index segments, and should return with an undefined index */ - return { type: "legacyMultiAlgoliaIndex", algoliaIndex: undefined }; + + if (docsDbDefinition.config.navigation == null && docsDbDefinition.config.root == null) { + return { type: "legacyMultiAlgoliaIndex", algoliaIndex }; + } + + if (docsDbDefinition.config.root != null) { + const latestRoot = FernNavigation.migrate.FernNavigationV1ToLatest.create().root(docsDbDefinition.config.root); + let searchInfo: Algolia.SearchInfo | undefined; + FernNavigation.traverseBF(latestRoot, (node) => { + if (node.type === "versioned") { + searchInfo = getVersionedSearchInfoFromDocs(activeIndexSegments, app); + return false; + } else if (node.type === "unversioned") { + searchInfo = getUnversionedSearchInfoFromDocs(activeIndexSegments, app); + return false; } - const searchApiKey = app.services.algoliaIndexSegmentManager.getOrGenerateSearchApiKeyForIndexSegment( - indexSegment.id, - ); + return true; + }); + if (searchInfo != null) { + return searchInfo; + } + } else if (docsDbDefinition.config.navigation != null) { + return visitDbNavigationConfig(docsDbDefinition.config.navigation, { + versioned: () => { + return getVersionedSearchInfoFromDocs(activeIndexSegments, app); + }, + unversioned: () => { + return getUnversionedSearchInfoFromDocs(activeIndexSegments, app); + }, + }); + } - return { - type: "singleAlgoliaIndex", - value: { - type: "unversioned", - indexSegment: { - id: FdrAPI.IndexSegmentId(indexSegment.id), - searchApiKey, - }, - }, - }; - }, - }); + return { type: "legacyMultiAlgoliaIndex", algoliaIndex }; } export function convertDbApiDefinitionToRead(buffer: Buffer): APIV1Read.ApiDefinition {