From bc580176ecdffd8c8ffe7d52f3c1a39e0687b89f Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 25 Jun 2024 13:33:34 -0400 Subject: [PATCH 1/2] Port `asset-preprocessing.js` to TypeScript (#51382) --- .../{asset-preprocessing.js => asset-preprocessing.ts} | 10 +++++++++- src/frame/middleware/index.ts | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) rename src/assets/middleware/{asset-preprocessing.js => asset-preprocessing.ts} (88%) diff --git a/src/assets/middleware/asset-preprocessing.js b/src/assets/middleware/asset-preprocessing.ts similarity index 88% rename from src/assets/middleware/asset-preprocessing.js rename to src/assets/middleware/asset-preprocessing.ts index 8bfc0fbc4b..1a5a1cd6d8 100644 --- a/src/assets/middleware/asset-preprocessing.js +++ b/src/assets/middleware/asset-preprocessing.ts @@ -1,3 +1,7 @@ +import type { Response, NextFunction } from 'express' + +import type { ExtendedRequest } from '@/types' + // This middleware rewrites the URL of requests that contain the // portion of `/cb-\d+/`. // "cb" stands for "cache bust". @@ -10,7 +14,11 @@ const regex = /\/cb-\d+\// -export default function assetPreprocessing(req, res, next) { +export default function assetPreprocessing( + req: ExtendedRequest, + res: Response, + next: NextFunction, +) { if (req.path.startsWith('/assets/')) { // We didn't use to have a rule about all image assets must be // lower case. So we've exposed things like: diff --git a/src/frame/middleware/index.ts b/src/frame/middleware/index.ts index 512e5ffdc9..4ec6baa8c3 100644 --- a/src/frame/middleware/index.ts +++ b/src/frame/middleware/index.ts @@ -52,7 +52,7 @@ import featuredLinks from '@/landings/middleware/featured-links.js' import learningTrack from '@/learning-track/middleware/learning-track.js' import next from './next.js' import renderPage from './render-page.js' -import assetPreprocessing from '@/assets/middleware/asset-preprocessing.js' +import assetPreprocessing from '@/assets/middleware/asset-preprocessing' import archivedAssetRedirects from '@/archives/middleware/archived-asset-redirects.js' import favicons from './favicons.js' import setStaticAssetCaching from '@/assets/middleware/static-asset-caching.js' From 8a6cc5908eb09dd3bcebc501d565be7128b5b7b4 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 25 Jun 2024 13:43:13 -0400 Subject: [PATCH 2/2] Port `featured-links.js` to TypeScript (#51385) --- src/frame/middleware/index.ts | 2 +- .../{featured-links.js => featured-links.ts} | 27 ++++++++---- .../{featured-links.js => featured-links.ts} | 4 +- src/types.ts | 41 +++++++++++++------ 4 files changed, 51 insertions(+), 23 deletions(-) rename src/landings/middleware/{featured-links.js => featured-links.ts} (72%) rename src/landings/tests/{featured-links.js => featured-links.ts} (93%) diff --git a/src/frame/middleware/index.ts b/src/frame/middleware/index.ts index 4ec6baa8c3..608dc5daf1 100644 --- a/src/frame/middleware/index.ts +++ b/src/frame/middleware/index.ts @@ -48,7 +48,7 @@ import renderProductName from './context/render-product-name' import features from '@/versions/middleware/features.js' import productExamples from './context/product-examples' import productGroups from './context/product-groups' -import featuredLinks from '@/landings/middleware/featured-links.js' +import featuredLinks from '@/landings/middleware/featured-links' import learningTrack from '@/learning-track/middleware/learning-track.js' import next from './next.js' import renderPage from './render-page.js' diff --git a/src/landings/middleware/featured-links.js b/src/landings/middleware/featured-links.ts similarity index 72% rename from src/landings/middleware/featured-links.js rename to src/landings/middleware/featured-links.ts index 0facbf3525..70edb636ba 100644 --- a/src/landings/middleware/featured-links.js +++ b/src/landings/middleware/featured-links.ts @@ -1,5 +1,8 @@ -import getLinkData from '#src/learning-track/lib/get-link-data.js' -import { renderContent } from '#src/content-render/index.js' +import type { Response, NextFunction } from 'express' + +import type { ExtendedRequest, FeaturedLinkExpanded } from '@/types' +import getLinkData from '@/learning-track/lib/get-link-data.js' +import { renderContent } from '@/content-render/index.js' /** * This is the max. number of featured links, by any category, that we @@ -24,7 +27,12 @@ import { renderContent } from '#src/content-render/index.js' const MAX_FEATURED_LINKS = 4 // this middleware adds properties to the context object -export default async function featuredLinks(req, res, next) { +export default async function featuredLinks( + req: ExtendedRequest, + res: Response, + next: NextFunction, +) { + if (!req.context) throw new Error('request is not contextualized') if (!req.context.page) return next() if ( @@ -46,7 +54,9 @@ export default async function featuredLinks(req, res, next) { // the provided string title or an empty title. When the title is empty, // it indicates the video is not versioned for the current version req.context.featuredLinks[key] = [] - for (const featuredLink of req.context.page.featuredLinks[key]) { + if (!(key in req.context.page.featuredLinks)) + throw new Error('featureLinks key not found in Page') + for (const featuredLink of req.context.page.featuredLinks[key]!) { const title = await renderContent(featuredLink.title, req.context, { textOnly: true, }) @@ -60,12 +70,15 @@ export default async function featuredLinks(req, res, next) { } } } else { - req.context.featuredLinks[key] = await getLinkData( - req.context.page.featuredLinks[key], + if (!(key in req.context.page.featuredLinks)) + throw new Error('featureLinks key not found in Page') + const pageFeaturedLink = req.context.page.featuredLinks[key] + req.context.featuredLinks[key] = (await getLinkData( + pageFeaturedLink, req.context, { title: true, intro: true, fullTitle: true }, MAX_FEATURED_LINKS, - ) + )) as FeaturedLinkExpanded[] // Remove ones `getLinkData` is TS } } diff --git a/src/landings/tests/featured-links.js b/src/landings/tests/featured-links.ts similarity index 93% rename from src/landings/tests/featured-links.js rename to src/landings/tests/featured-links.ts index fcc09a1632..3b4048147c 100644 --- a/src/landings/tests/featured-links.js +++ b/src/landings/tests/featured-links.ts @@ -1,7 +1,7 @@ import { describe, expect, test, vi } from 'vitest' -import { getDOM } from '#src/tests/helpers/e2etest.js' -import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js' +import { getDOM } from '@/tests/helpers/e2etest.js' +import enterpriseServerReleases from '@/versions/lib/enterprise-server-releases.js' describe('featuredLinks', () => { vi.setConfig({ testTimeout: 60 * 1000 }) diff --git a/src/types.ts b/src/types.ts index 0b5ba99841..f0459077bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,19 +36,7 @@ export type PageFrontmatter = { authors?: string[] examples_source?: string effectiveDate?: string - - featuredLinks?: { - gettingStarted?: string[] - startHere?: string[] - guideCards?: string[] - popular?: string[] - popularHeading?: string - videos?: { - title: string - href: string - }[] - videoHeadings?: string - }[] + featuredLinks?: FeaturedLinks changelog?: ChangeLog type?: string topics?: string[] @@ -67,6 +55,19 @@ export type PageFrontmatter = { childGroups?: ChildGroup[] } +type FeaturedLinks = { + gettingStarted?: string[] + startHere?: string[] + guideCards?: string[] + popular?: string[] + popularHeading?: string + videos?: { + title: string + href: string + }[] + videoHeadings?: string +} + export type ChildGroup = { name: string octicon: string @@ -157,6 +158,19 @@ export type Context = { productCommunityExamples?: ProductExample[] productUserExamples?: ProductExample[] productGroups?: ProductGroup[] + featuredLinks?: FeaturedLinksExpanded +} + +export type FeaturedLinkExpanded = { + href: string + title: string + page?: Page + fullTitle?: string + intro?: string +} + +type FeaturedLinksExpanded = { + [key: string]: FeaturedLinkExpanded[] } export type ProductGroup = { @@ -296,6 +310,7 @@ export type Page = { layout?: string | boolean earlyAccessToc?: boolean autogenerated?: string + featuredLinks?: FeaturedLinksExpanded } type ChangeLog = {