1
0
mirror of synced 2025-12-22 03:16:52 -05:00
Files
docs/lib/get-product-groups.js
2023-08-09 20:31:53 +00:00

92 lines
3.4 KiB
JavaScript

import path from 'path'
import { productMap, data } from './all-products.js'
import { renderContentWithFallback } from './render-with-fallback.js'
import removeFPTFromPath from './remove-fpt-from-path.js'
async function getPage(id, lang, pageMap, context) {
const productId = id.split('/')[0]
const product = productMap[productId]
const external = product.external || false // undefined becomes false
// The href depends. Initially all we have is an `id` which might be
// something like 'code-security/dependabot'.
// To get from that to a Page instance, we have to "guess" what the
// href might be.
// If URL currently is `/fr/enterprise-server@3.9`,
// we're going to try `/fr/enterprise-server@3.9/code-security/dependabot`
// first. And if the URL is `/en` we'll try `/en/code-security/dependabot`.
// But some pages are not available in all versions.
// So we have to try `product.versions[0]` which comes from the `productMap`
// (not be confused with the `pageMap`!)
// Once we have a page, we can get to its `.applicableVersions`.
// This way, we get the best of both worlds. We use the `currentVersion`
// if it's applicable, but we fall back to the first version if it's not.
let href = product.href
let name = product.name
if (!external) {
// First we have to find it as a page object based on its ID.
href = removeFPTFromPath(path.posix.join('/', lang, context.currentVersion, id))
if (!pageMap[href]) {
// If the page is not available in the *current* version, we
// fall back it its default version, which is `product.versions[0]`.
// For example, you're on `/en/enterprise-server@3.1` and you're
// but a `/foo/bar` is only available in `enterprise-cloud@latest`.
href = removeFPTFromPath(path.posix.join('/', lang, product.versions[0], id))
}
const page = pageMap[href]
if (!page) {
throw new Error(
`Unable to find a page by the href '${href}'. Review your 'childGroups' front matter.`,
)
}
// Some should not be included for the current version, and returning
// undefined here means this entry will be filtered out by the caller.
const isFPT = context.currentVersion === 'free-pro-team@latest'
if (!isFPT && !page.applicableVersions.includes(context.currentVersion)) {
return
}
if (page.rawShortTitle) {
name = await renderContentWithFallback(page, 'rawShortTitle', context, {
textOnly: true,
throwIfEmpty: false,
})
}
// Either the page didn't have a `rawShortTitle` or it was empty when
// rendered out with Liquid. Either way, have to fall back to `rawTitle`.
if (!name) {
name = await renderContentWithFallback(page, 'rawTitle', context, {
textOnly: true,
})
}
}
// Return only the props needed for the ProductSelectionCard, since
// that's the only place this is ever used.
return {
id,
name,
href,
external,
}
}
export async function getProductGroups(pageMap, lang, context) {
return await Promise.all(
data.childGroups.map(async (group) => {
return {
name: group.name,
icon: group.icon || null,
octicon: group.octicon || null,
// Typically the children are product IDs, but we support deeper page paths too
children: (
await Promise.all(group.children.map((id) => getPage(id, lang, pageMap, context)))
).filter(Boolean),
}
}),
)
}