92 lines
3.4 KiB
JavaScript
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),
|
|
}
|
|
}),
|
|
)
|
|
}
|