(req)
| 251 | const fallbackRedirectLookups = new Map() |
| 252 | |
| 253 | function getFallbackRedirect(req) { |
| 254 | // The file `lib/redirects/static/archived-frontmatter-valid-urls.json` which |
| 255 | // we depend on here, is structured like this: |
| 256 | // |
| 257 | // { |
| 258 | // "/enterprise/2.13/foo/bar": [ |
| 259 | // "/enterprise/2.13/other/old/thing", |
| 260 | // "/enterprise/2.13/more/redirectable/url", |
| 261 | // "/enterprise/2.13/etc/etc" |
| 262 | // ], |
| 263 | // ... |
| 264 | // |
| 265 | // The keys are valid URLs that it can redirect to. I.e. these are |
| 266 | // URLs that we definitely know are valid and will be found |
| 267 | // in https://github.com/github/help-docs-archived-enterprise-versions |
| 268 | // The array values are possible URLs we deem acceptable redirect |
| 269 | // sources. |
| 270 | // But to avoid an unnecessary, O(n), loop every time, we turn this |
| 271 | // structure around to become: |
| 272 | // |
| 273 | // { |
| 274 | // "/enterprise/2.13/other/old/thing": "/enterprise/2.13/foo/bar", |
| 275 | // "/enterprise/2.13/more/redirectable/url": "/enterprise/2.13/foo/bar", |
| 276 | // "/enterprise/2.13/etc/etc": "/enterprise/2.13/foo/bar", |
| 277 | // ... |
| 278 | // |
| 279 | // Now potential lookups are fast. |
| 280 | if (!fallbackRedirectLookups.size) { |
| 281 | for (const [destination, sources] of Object.entries(archivedFrontmatterValidURLS())) { |
| 282 | for (const source of sources) { |
| 283 | fallbackRedirectLookups.set(source, destination) |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | // But before we proceed, remember that the |
| 289 | // file lib/redirects/static/archived-frontmatter-valid-urls.json never |
| 290 | // contains a language prefix. |
| 291 | // E.g. only `/enterprise/2.13/foo/bar` but the requested URL can be |
| 292 | // `/en/enterprise/2.13/foo/bar`, `/pt/enterprise/2.13/foo/bar`, |
| 293 | // or just `/enterprise/2.13/foo/bar`. |
| 294 | // Whatever it is, pop the language prefix, operate, and put it back |
| 295 | // again. In the end, it always has to have a language prefix. |
| 296 | const [language, withoutLanguage] = splitPathByLanguage(req.path) |
| 297 | const fallback = fallbackRedirectLookups.get(withoutLanguage) |
| 298 | if (fallback) { |
| 299 | return `/${language}${fallback}` |
| 300 | } |
| 301 | } |
no test coverage detected