1
0
mirror of synced 2025-12-19 18:10:59 -05:00
Files
docs/lib/page-data.js
Kevin Heis 42e785b0a8 Migrate CommonJS to ESM (#20301)
* First run of script

* Get the app running --- ish

* Get NextJS working

* Remove `node:`

* Get more tests passing in unit directory

* Update FailBot test to use nock

* Update test.yml

* Update Dockerfile

* tests/content fixes

* Update page.js

* Update build-changelog.js

* updating tests/routing

* Update orphan-tests.js

* updating tests/rendering

* Update .eslintrc.js

* Update .eslintrc.js

* Install jest/globals

* "linting" tests

* staging update to server.mjs

* Change '.github/allowed-actions.js' to a ESM export

* Lint

* Fixes for the main package.json

* Move Jest to be last in the npm test command so we can pass args

* Just use 'npm run lint' in the npm test command

* update algolia label script

* update openapi script

* update require on openapi

* Update enterprise-algolia-label.js

* forgot JSON.parse

* Update lunr-search-index.js

* Always explicitly include process.cwd() for JSON file reads pathed from project root

* update graphql/update-files.js script

* Update other npm scripts using jest to pass ESM NODE_OPTIONS

* Update check-for-enterprise-issues-by-label.js for ESM

* Update create-enterprise-issue.js for ESM

* Import jest global for browser tests

* Convert 'script/deploy' to ESM

Co-authored-by: Grace Park <gracepark@github.com>
Co-authored-by: James M. Greene <jamesmgreene@github.com>
2021-07-14 13:49:18 -07:00

151 lines
5.3 KiB
JavaScript

import { fileURLToPath } from 'url'
import path from 'path'
import languages from './languages.js'
import xAllVersions from './all-versions.js'
import createTree from './create-tree.js'
import renderContent from './render-content/index.js'
import loadSiteData from './site-data.js'
import nonEnterpriseDefaultVersion from './non-enterprise-default-version.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const versions = Object.keys(xAllVersions)
const enterpriseServerVersions = versions.filter(v => v.startsWith('enterprise-server@'))
const renderOpts = { textOnly: true, encodeEntities: true }
/**
* We only need to initialize pages _once per language_ since pages don't change per version. So we do that
* first since it's the most expensive work. This gets us a nested object with pages attached that we can use
* as the basis for the siteTree after we do some versioning. We can also use it to derive the pageList.
*/
export async function loadUnversionedTree () {
const unversionedTree = {}
await Promise.all(Object.values(languages)
.map(async (langObj) => {
const localizedContentPath = path.posix.join(__dirname, '..', langObj.dir, 'content')
unversionedTree[langObj.code] = await createTree(localizedContentPath, langObj)
}))
return unversionedTree
}
/**
* The siteTree is a nested object with pages for every language and version, useful for nav because it
* contains parent, child, and sibling relationships:
*
* siteTree[languageCode][version].childPages[<array of pages>].childPages[<array of pages>] (etc...)
* Given an unversioned tree of all pages per language, we can walk it for each version and do a couple operations:
* 1. Add a versioned href to every item, where the href is the relevant permalink for the current version.
* 2. Drop any child pages that are not available in the current version.
*
* Order of languages and versions doesn't matter, but order of child page arrays DOES matter (for navigation).
*/
export async function loadSiteTree (unversionedTree, siteData) {
const site = siteData || loadSiteData()
const rawTree = Object.assign({}, (unversionedTree || await loadUnversionedTree()))
const siteTree = {}
// For every language...
await Promise.all(Object.keys(languages).map(async (langCode) => {
const treePerVersion = {}
// in every version...
await Promise.all(versions.map(async (version) => {
// "version" the pages.
treePerVersion[version] = await versionPages(Object.assign({}, rawTree[langCode]), version, langCode, site)
}))
siteTree[langCode] = treePerVersion
}))
return siteTree
}
export async function versionPages (obj, version, langCode, site) {
// Add a versioned href as a convenience for use in layouts.
obj.href = obj.page.permalinks
.find(pl => pl.pageVersion === version || (pl.pageVersion === 'homepage' && version === nonEnterpriseDefaultVersion))
.href
const context = {
currentLanguage: langCode,
currentVersion: version,
enterpriseServerVersions,
site: site[langCode].site
}
// The Liquid parseAndRender method is MUCH faster than renderContent or renderProp.
// This only works for titles and short titles, which have no other Markdown that needs
// to be converted to HTML, so we can get away with _only_ parsing Liquid.
obj.renderedFullTitle = obj.page.title.includes('{')
? await renderContent.liquid.parseAndRender(obj.page.title, context, renderOpts)
: obj.page.title
if (obj.page.shortTitle) {
obj.renderedShortTitle = obj.page.shortTitle.includes('{')
? await renderContent.liquid.parseAndRender(obj.page.shortTitle, context, renderOpts)
: obj.page.shortTitle
}
if (!obj.childPages) return obj
const versionedChildPages = await Promise.all(obj.childPages
// Drop child pages that do not apply to the current version.
.filter(childPage => childPage.page.applicableVersions.includes(version))
// Version the child pages recursively.
.map(childPage => versionPages(Object.assign({}, childPage), version, langCode, site)))
obj.childPages = [...versionedChildPages]
return obj
}
// Derive a flat array of Page objects in all languages.
export async function loadPageList (unversionedTree) {
const rawTree = unversionedTree || await loadUnversionedTree()
const pageList = []
await Promise.all(Object.keys(languages).map(async (langCode) => {
await addToCollection(rawTree[langCode], pageList)
}))
async function addToCollection (item, collection) {
if (!item.page) return
collection.push(item.page)
if (!item.childPages) return
await Promise.all(item.childPages.map(async (childPage) => await addToCollection(childPage, collection)))
}
return pageList
}
export const loadPages = loadPageList
// Create an object from the list of all pages with permalinks as keys for fast lookup.
export function createMapFromArray (pageList) {
const pageMap =
pageList.reduce(
(pageMap, page) => {
for (const permalink of page.permalinks) {
pageMap[permalink.href] = page
}
return pageMap
},
{}
)
return pageMap
}
export async function loadPageMap (pageList) {
const pages = pageList || await loadPageList()
return createMapFromArray(pages)
}
export default {
loadUnversionedTree,
loadSiteTree,
loadPages: loadPageList,
loadPageMap
}