| import { readCompressedJsonFileFallback } from '@/frame/lib/read-json-file' | |
| import getExceptionRedirects from './exception-redirects' | |
| import { latest } from '@/versions/lib/enterprise-server-releases' | |
| import type { Page } from '@/types' | |
| const EXCEPTIONS_FILE = './src/redirects/lib/static/redirect-exceptions.txt' | |
| type Redirects = Record<string, string> | |
| // This function runs at server warmup and precompiles possible redirect routes. | |
| // It outputs them in key-value pairs within a neat JavaScript object: { oldPath: newPath } | |
| export async function precompileRedirects(pageList: Page[]): Promise<Redirects> { | |
| const allRedirects: Redirects = readCompressedJsonFileFallback( | |
| './src/redirects/lib/static/developer.json', | |
| ) | |
| const externalRedirects: Redirects = readCompressedJsonFileFallback( | |
| './src/redirects/lib/external-sites.json', | |
| ) | |
| Object.assign(allRedirects, externalRedirects) | |
| // CURRENT PAGES PERMALINKS AND FRONTMATTER | |
| // create backwards-compatible old paths for page permalinks and frontmatter redirects | |
| for (const page of pageList.filter((xpage) => xpage.languageCode === 'en')) { | |
| Object.assign(allRedirects, page.buildRedirects()) | |
| } | |
| // NOTE: Exception redirects **MUST COME AFTER** pageList redirects above in order | |
| // to properly override them. Exception redirects are unicorn one-offs that are not | |
| // otherwise handled by the versionless redirect fallbacks (see lib/all-versions.ts). | |
| // | |
| // Examples of exceptions: | |
| // * We deprecate the FPT version of a page, and we want the FPT version to redirect | |
| // to a different version that goes against the order in lib/all-versions.ts. | |
| // * We deprecate a non-FPT version of a page, and we want the old version to redirect | |
| // to a different version. Because the order in lib/all-versions.ts only covers | |
| // versionless links (like `/foo`), we need to specify an exception for the old | |
| // versioned links (like `/enterprise-cloud@latest/foo`). | |
| // * We deprecate a version of a page, and instead of falling back to the next | |
| // available version, we want to redirect that version to a different page entirely. | |
| // | |
| // The advantage of the exception redirects file is that it's encoded in plain | |
| // text so it's possible to write comments and it's also possible to write 1 | |
| // destination URL once for each N redirect origins. | |
| const exceptions = getExceptionRedirects(EXCEPTIONS_FILE) as Redirects | |
| Object.assign(allRedirects, exceptions) | |
| for (const [fromURI, toURI] of Object.entries(allRedirects)) { | |
| // If the destination URL has a hardcoded `enterprise-server@latest` in | |
| // it we need to rewrite that now. | |
| // We never want to redirect to that as the final URL (in the 301 response) | |
| // but it might make sense for it to be in the `developer.json` | |
| // file since that it static. | |
| // | |
| // | |
| if (toURI.includes('/enterprise-server@latest')) { | |
| allRedirects[fromURI] = toURI.replace( | |
| '/enterprise-server@latest', | |
| `/enterprise-server@${latest}`, | |
| ) | |
| } | |
| } | |
| return allRedirects | |
| } | |
| export default precompileRedirects | |