From e94df405707a37be6653821b12ec354f5c96a6a5 Mon Sep 17 00:00:00 2001 From: Zach Shilton <4624598+zchsh@users.noreply.github.com> Date: Tue, 26 Sep 2023 18:02:26 -0400 Subject: [PATCH] fix(openapi): revise default version logic (#2180) * feat: implement find-default-version * fix: use findDefaultVersion * chore: clean up unused imports * fix: avoid potential undefined in static props * chore: rm unused find-latest-stable-version * style: clearer distinction in comment --- src/views/open-api-docs-view/server.ts | 10 ++--- .../utils/find-default-version.ts | 39 +++++++++++++++++++ .../utils/find-latest-stable-version.ts | 29 -------------- src/views/open-api-docs-view/utils/index.ts | 2 +- 4 files changed, 43 insertions(+), 37 deletions(-) create mode 100644 src/views/open-api-docs-view/utils/find-default-version.ts delete mode 100644 src/views/open-api-docs-view/utils/find-latest-stable-version.ts diff --git a/src/views/open-api-docs-view/server.ts b/src/views/open-api-docs-view/server.ts index 2ed96f3a7a..69025e1307 100644 --- a/src/views/open-api-docs-view/server.ts +++ b/src/views/open-api-docs-view/server.ts @@ -12,7 +12,7 @@ import { getBreadcrumbLinks } from 'lib/get-breadcrumb-links' import { serialize } from 'next-mdx-remote/serialize' // Utilities import { - findLatestStableVersion, + findDefaultVersion, getNavItems, getOperationProps, groupOperations, @@ -25,13 +25,10 @@ import type { GetStaticPropsResult, } from 'next' import type { OpenAPIV3 } from 'openapi-types' -import type { ProductSlug } from 'types/products' import type { OpenApiDocsParams, OpenApiDocsViewProps, OpenApiDocsVersionData, - StatusIndicatorConfig, - OpenApiNavItem, OpenApiDocsPageConfig, } from './types' @@ -71,7 +68,7 @@ export async function getStaticProps({ serviceProductSlug = productSlug, versionData, basePath, - statusIndicatorConfig, + statusIndicatorConfig = null, // must be JSON-serializable topOfPageId = 'overview', groupOperationsByPath = false, massageSchemaForClient = (s: OpenAPIV3.Document) => s, @@ -89,13 +86,12 @@ export async function getStaticProps({ const pathParts = context.params?.page const versionId = pathParts?.length > 1 ? pathParts[0] : null const isVersionedUrl = typeof versionId === 'string' - const latestStableVersion = findLatestStableVersion(versionData) // Resolve the current version let targetVersion: OpenApiDocsVersionData | undefined if (isVersionedUrl) { targetVersion = versionData.find((v) => v.versionId === versionId) } else { - targetVersion = latestStableVersion + targetVersion = findDefaultVersion(versionData) } // If we can't resolve the current version, render a 404 page if (!targetVersion) { diff --git a/src/views/open-api-docs-view/utils/find-default-version.ts b/src/views/open-api-docs-view/utils/find-default-version.ts new file mode 100644 index 0000000000..add921babf --- /dev/null +++ b/src/views/open-api-docs-view/utils/find-default-version.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { OpenApiDocsVersionData } from '../types' +import { sortDateVersionData } from './sort-date-version-data' + +/** + * Given an array of version data, + * Return the default version that should be shown. + * + * - If there is exactly one version, we treat it as the default version. + * - If there are multiple versions, but no `stable` version, we'll show + * the very latest version as the default version (even if not `stable`). + * - If there are multiple versions, and at least one `stable` version, + * we'll show the latest `stable` version as the default version. + * + * Note: only supports date-based version formats, for example "2023-01-15". + * We'd need to update the sort logic in order to support other formats. + */ +export function findDefaultVersion( + versionData: OpenApiDocsVersionData[] +): OpenApiDocsVersionData { + // If we have exactly one version, we'll show that as the default. + if (versionData.length === 1) { + return versionData[0] + } + // Sort versions in descending order + const versionsDescending = sortDateVersionData(versionData) + // Ideally, we'll show the latest 'stable' release as the default. + const latestStableVersion = versionsDescending.find( + (v) => v.releaseStage === 'stable' + ) + // Fall back to the latest version (any stage!) if there's no 'stable' version + const defaultVersion = latestStableVersion || versionsDescending[0] + // Return the default version + return defaultVersion +} diff --git a/src/views/open-api-docs-view/utils/find-latest-stable-version.ts b/src/views/open-api-docs-view/utils/find-latest-stable-version.ts deleted file mode 100644 index 349c12370c..0000000000 --- a/src/views/open-api-docs-view/utils/find-latest-stable-version.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: MPL-2.0 - */ - -import { OpenApiDocsVersionData } from '../types' -import { sortDateVersionData } from './sort-date-version-data' - -/** - * Given an array of version data, - * Return the latest `stable` version. - * - * Note: only supports date-based version formats, for example "2023-01-15". - * We'd need to update the sort logic in order to support other formats. - */ -function findLatestStableVersion( - versionData: OpenApiDocsVersionData[] -): OpenApiDocsVersionData { - // If we have exactly one version, we assume it's the latest stable version. - if (versionData.length === 1) { - return versionData[0] - } - // Sort versions in descending order - const versionsDescending = sortDateVersionData(versionData) - // Return the first 'stable' release we can find in descending versions - return versionsDescending.find((v) => v.releaseStage === 'stable') -} - -export { findLatestStableVersion } diff --git a/src/views/open-api-docs-view/utils/index.ts b/src/views/open-api-docs-view/utils/index.ts index f806285114..8b64381c4b 100644 --- a/src/views/open-api-docs-view/utils/index.ts +++ b/src/views/open-api-docs-view/utils/index.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: MPL-2.0 */ -export { findLatestStableVersion } from './find-latest-stable-version' +export { findDefaultVersion } from './find-default-version' export { getNavItems } from './get-nav-items' export { getOperationProps } from './get-operation-props' export {