| import fs from 'fs' |
| import path from 'path' |
|
|
| import express from 'express' |
| import type { NextFunction, Request, Response, Express } from 'express' |
| import timeout from 'connect-timeout' |
|
|
| import { haltOnDroppedConnection } from './halt-on-dropped-connection' |
| import abort from './abort' |
| import helmet from './helmet' |
| import cookieParser from './cookie-parser' |
| import { |
| setDefaultFastlySurrogateKey, |
| setLanguageFastlySurrogateKey, |
| } from './set-fastly-surrogate-key' |
| import handleErrors from '@/observability/middleware/handle-errors' |
| import handleNextDataPath from './handle-next-data-path' |
| import detectLanguage from '@/languages/middleware/detect-language' |
| import reloadTree from './reload-tree' |
| import context from './context/context' |
| import shortVersions from '@/versions/middleware/short-versions' |
| import languageCodeRedirects from '@/redirects/middleware/language-code-redirects' |
| import handleRedirects from '@/redirects/middleware/handle-redirects' |
| import findPage from './find-page' |
| import blockRobots from './block-robots' |
| import archivedEnterpriseVersionsAssets from '@/archives/middleware/archived-enterprise-versions-assets' |
| import api from './api' |
| import llmsTxt from './llms-txt' |
| import healthcheck from './healthcheck' |
| import manifestJson from './manifest-json' |
| import buildInfo from './build-info' |
| import reqHeaders from './req-headers' |
| import archivedEnterpriseVersions from '@/archives/middleware/archived-enterprise-versions' |
| import robots from './robots' |
| import earlyAccessLinks from '@/early-access/middleware/early-access-links' |
| import categoriesForSupport from './categories-for-support' |
| import triggerError from '@/observability/middleware/trigger-error' |
| import dataTables from '@/data-directory/middleware/data-tables' |
| import secretScanning from '@/secret-scanning/middleware/secret-scanning' |
| import ghesReleaseNotes from '@/release-notes/middleware/ghes-release-notes' |
| import whatsNewChangelog from './context/whats-new-changelog' |
| import layout from './context/layout' |
| import currentProductTree from './context/current-product-tree' |
| import genericToc from './context/generic-toc' |
| import breadcrumbs from './context/breadcrumbs' |
| import glossaries from './context/glossaries' |
| import resolveRecommended from './resolve-recommended' |
| import renderProductName from './context/render-product-name' |
| import features from '@/versions/middleware/features' |
| import productExamples from './context/product-examples' |
| import productGroups from './context/product-groups' |
| import featuredLinks from '@/landings/middleware/featured-links' |
| import learningTrack from '@/learning-track/middleware/learning-track' |
| import journeyTrack from '@/journeys/middleware/journey-track' |
| import next from './next' |
| import renderPage from './render-page' |
| import assetPreprocessing from '@/assets/middleware/asset-preprocessing' |
| import archivedAssetRedirects from '@/archives/middleware/archived-asset-redirects' |
| import favicons from './favicons' |
| import setStaticAssetCaching from '@/assets/middleware/static-asset-caching' |
| import fastHead from './fast-head' |
| import fastlyCacheTest from './fastly-cache-test' |
| import trailingSlashes from './trailing-slashes' |
| import mockVaPortal from './mock-va-portal' |
| import dynamicAssets from '@/assets/middleware/dynamic-assets' |
| import generalSearchMiddleware from '@/search/middleware/general-search-middleware' |
| import shielding from '@/shielding/middleware' |
| import { MAX_REQUEST_TIMEOUT } from '@/frame/lib/constants' |
| import { initLoggerContext } from '@/observability/logger/lib/logger-context' |
| import { getAutomaticRequestLogger } from '@/observability/logger/middleware/get-automatic-request-logger' |
| import appRouterGateway from './app-router-gateway' |
| import urlDecode from './url-decode' |
|
|
| const { NODE_ENV } = process.env |
| const isTest = NODE_ENV === 'test' || process.env.GITHUB_ACTIONS === 'true' |
|
|
| const ENABLE_FASTLY_TESTING = JSON.parse(process.env.ENABLE_FASTLY_TESTING || 'false') |
|
|
| |
| |
| const asyncMiddleware = |
| <TReq extends Request = Request, T = void>( |
| fn: (req: TReq, res: Response, next: NextFunction) => T | Promise<T>, |
| ) => |
| async (req: Request, res: Response, nextFn: NextFunction) => { |
| try { |
| await fn(req as TReq, res, nextFn) |
| } catch (error) { |
| nextFn(error) |
| } |
| } |
|
|
| export default function index(app: Express) { |
| |
| if (!isTest) app.use(timeout(MAX_REQUEST_TIMEOUT)) |
| app.use(abort) |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| app.set('trust proxy', true) |
|
|
| |
| app.use(initLoggerContext) |
| app.use(getAutomaticRequestLogger()) |
|
|
| |
| |
| app.use('/healthcheck', healthcheck) |
|
|
| |
| |
| |
| app.use(setDefaultFastlySurrogateKey) |
|
|
| |
| app.use(asyncMiddleware(archivedEnterpriseVersionsAssets)) |
|
|
| app.use(favicons) |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| app.use(setStaticAssetCaching) |
|
|
| |
| app.use(archivedAssetRedirects) |
|
|
| |
| app.use(assetPreprocessing) |
|
|
| app.use( |
| '/assets/', |
| express.static('assets', { |
| index: false, |
| etag: false, |
| |
| |
| maxAge: '7 days', |
| immutable: process.env.NODE_ENV !== 'development', |
| |
| fallthrough: true, |
| }), |
| ) |
| app.use(asyncMiddleware(dynamicAssets)) |
| app.use( |
| '/public/', |
| express.static('src/graphql/data', { |
| index: false, |
| etag: false, |
| maxAge: '7 days', |
| |
| fallthrough: false, |
| }), |
| ) |
|
|
| |
| |
| |
| if (process.env.NODE_ENV !== 'development') { |
| const assetDir = path.join('.next', 'static') |
| if (!fs.existsSync(assetDir)) |
| throw new Error(`${assetDir} directory has not been generated. Run 'npm run build' first.`) |
|
|
| app.use( |
| '/_next/static/', |
| express.static(assetDir, { |
| index: false, |
| etag: false, |
| maxAge: '365 days', |
| immutable: true, |
| |
| fallthrough: false, |
| }), |
| ) |
| } |
|
|
| |
| app.use(shielding) |
| app.use(handleNextDataPath) |
|
|
| |
| app.use(helmet) |
| app.use(cookieParser) |
| app.use(express.json()) |
|
|
| if (process.env.NODE_ENV === 'development') { |
| app.use(mockVaPortal) |
| } |
|
|
| |
|
|
| |
| app.set('etag', false) |
|
|
| |
| app.use(urlDecode) |
| app.use(detectLanguage) |
| app.use(asyncMiddleware(reloadTree)) |
| app.use(asyncMiddleware(context)) |
| app.use(shortVersions) |
| app.use(asyncMiddleware(renderProductName)) |
|
|
| |
| |
| app.use(asyncMiddleware(archivedEnterpriseVersions)) |
|
|
| |
| |
| app.use(trailingSlashes) |
| app.use(languageCodeRedirects) |
| app.use(handleRedirects) |
|
|
| |
| app.use(asyncMiddleware(findPage)) |
| app.use(blockRobots) |
|
|
| |
| app.use(haltOnDroppedConnection) |
|
|
| |
| app.use(asyncMiddleware(appRouterGateway)) |
|
|
| |
| app.use('/api', api) |
| app.use('/llms.txt', llmsTxt) |
| app.get('/_build', buildInfo) |
| app.get('/_req-headers', reqHeaders) |
| app.use(asyncMiddleware(manifestJson)) |
|
|
| |
| |
| app.use(setLanguageFastlySurrogateKey) |
|
|
| |
| app.use(haltOnDroppedConnection) |
|
|
| app.use(robots) |
| app.use(earlyAccessLinks) |
| app.use('/categories.json', asyncMiddleware(categoriesForSupport)) |
| app.get('/_500', asyncMiddleware(triggerError)) |
|
|
| |
| app.use(haltOnDroppedConnection) |
|
|
| |
| |
| app.head('/*path', fastHead) |
|
|
| |
| app.use(asyncMiddleware(dataTables)) |
| app.use(asyncMiddleware(secretScanning)) |
| app.use(asyncMiddleware(ghesReleaseNotes)) |
| app.use(asyncMiddleware(whatsNewChangelog)) |
| app.use(layout) |
| app.use(features) |
| app.use(asyncMiddleware(currentProductTree)) |
| app.use(asyncMiddleware(genericToc)) |
| app.use(breadcrumbs) |
| app.use(asyncMiddleware(productExamples)) |
| app.use(asyncMiddleware(productGroups)) |
| app.use(asyncMiddleware(glossaries)) |
| app.use(asyncMiddleware(generalSearchMiddleware)) |
| app.use(asyncMiddleware(featuredLinks)) |
| app.use(asyncMiddleware(resolveRecommended)) |
| app.use(asyncMiddleware(learningTrack)) |
| app.use(asyncMiddleware(journeyTrack)) |
|
|
| if (ENABLE_FASTLY_TESTING) { |
| |
| |
| |
| app.use('/fastly-cache-test', fastlyCacheTest) |
| } |
|
|
| |
| app.use(next) |
|
|
| |
| app.use(haltOnDroppedConnection) |
|
|
| |
| app.get('/*path', asyncMiddleware(renderPage)) |
|
|
| |
| app.use(handleErrors) |
| } |
|
|