Skip to content

Commit

Permalink
Merge pull request #33717 from github/repo-sync
Browse files Browse the repository at this point in the history
Repo sync
  • Loading branch information
docs-bot authored Jun 26, 2024
2 parents 9540910 + 850ee72 commit 0375507
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 56 deletions.
4 changes: 2 additions & 2 deletions src/content-render/scripts/all-documents/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Response } from 'express'

import type { ExtendedRequest, Page } from '@/types'
import contextualize from '@/frame/middleware/context/context'
import features from '@/versions/middleware/features.js'
import features from '@/versions/middleware/features'
import shortVersions from '@/versions/middleware/short-versions.js'

import warmServer from '@/frame/lib/warm-server.js'
Expand Down Expand Up @@ -68,7 +68,7 @@ export async function allDocuments(options: Options): Promise<AllDocument[]> {
await contextualize(req as ExtendedRequest, res as Response, next)
await shortVersions(req, res, next)
req.context.page = page
await features(req, res, next)
features(req as any, res as any, next)

const title = fields.includes('title')
? await page.renderProp('title', req.context, { textOnly: true })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { describe, expect, test, vi } from 'vitest'
import type { Response } from 'express'

import { liquid } from '#src/content-render/index.js'
import shortVersionsMiddleware from '#src/versions/middleware/short-versions.js'
import featureVersionsMiddleware from '#src/versions/middleware/features.js'
import { allVersions } from '#src/versions/lib/all-versions.js'
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
import { liquid } from '@/content-render/index.js'
import shortVersionsMiddleware from '@/versions/middleware/short-versions.js'
import featureVersionsMiddleware from '@/versions/middleware/features'
import { allVersions } from '@/versions/lib/all-versions.js'
import enterpriseServerReleases from '@/versions/lib/enterprise-server-releases.js'
import type { Context, ExtendedRequest, Page } from '@/types'

// Setup these variables so we don't need to manually update tests as GHES
// versions continually get deprecated. For example, if we deprecate GHES 3.0,
Expand Down Expand Up @@ -37,8 +39,10 @@ const featureVersionsTemplate = `
{% if placeholder %} I am placeholder content {% endif %}
`

const contextualize = (req) => {
req.context.currentVersionObj = req.context.allVersions[req.context.currentVersion]
const contextualize = (req: ExtendedRequest) => {
if (!req.context || !req.context.allVersions || !req.context.currentVersion)
throw new Error('request not contextualized')
req.context!.currentVersionObj = req.context.allVersions[req.context.currentVersion]
shortVersionsMiddleware(req, null, () => {})
}

Expand All @@ -47,15 +51,14 @@ describe('liquid template parser', () => {

describe('short versions', () => {
// Create a fake req so we can test the shortVersions middleware
const req = { language: 'en', query: {} }
const req = { language: 'en', query: {} } as ExtendedRequest

test('FPT works as expected when it is FPT', async () => {
req.context = {
currentVersion: 'free-pro-team@latest',
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(shortVersionsTemplate, req.context)
// We should have TWO results because we are supporting two shortcuts
Expand All @@ -67,10 +70,10 @@ describe('liquid template parser', () => {
test('GHEC works as expected', async () => {
req.context = {
currentVersion: 'enterprise-cloud@latest',
page: {},
// page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(shortVersionsTemplate, req.context)
expect(output.trim()).toBe('I am GHEC')
Expand All @@ -79,10 +82,9 @@ describe('liquid template parser', () => {
test('GHES works as expected', async () => {
req.context = {
currentVersion: `enterprise-server@${oldestSupportedGhes}`,
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(shortVersionsTemplate, req.context)
expect(output.replace(/\s\s+/g, ' ').trim()).toBe(
Expand All @@ -93,10 +95,9 @@ describe('liquid template parser', () => {
test('AND statements work as expected', async () => {
req.context = {
currentVersion: `enterprise-server@${secondOldestSupportedGhes}`,
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(shortVersionsTemplate, req.context)
expect(output.replace(/\s\s+/g, ' ').trim()).toBe(
Expand All @@ -107,10 +108,9 @@ describe('liquid template parser', () => {
test('NOT statements work as expected on versions without numbered releases', async () => {
req.context = {
currentVersion: 'free-pro-team@latest',
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(negativeVersionsTemplate, req.context)
expect(output.replace(/\s\s+/g, ' ').trim()).toBe(
Expand All @@ -121,10 +121,9 @@ describe('liquid template parser', () => {
test('NOT statements work as expected on versions with numbered releases', async () => {
req.context = {
currentVersion: `enterprise-server@${oldestSupportedGhes}`,
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(negativeVersionsTemplate, req.context)
expect(output.replace(/\s\s+/g, ' ').trim()).toBe(
Expand All @@ -135,10 +134,9 @@ describe('liquid template parser', () => {
test('The != operator works as expected', async () => {
req.context = {
currentVersion: `enterprise-server@${secondOldestSupportedGhes}`,
page: {},
allVersions,
enterpriseServerReleases,
}
} as Context
contextualize(req)
const output = await liquid.parseAndRender(negativeVersionsTemplate, req.context)
expect(output.replace(/\s\s+/g, ' ').trim()).toBe('I am not GHEC')
Expand All @@ -147,42 +145,42 @@ describe('liquid template parser', () => {

describe('feature versions', () => {
// Create a fake req so we can test the feature versions middleware
const req = { language: 'en', query: {} }
const req = { language: 'en', query: {} } as ExtendedRequest

test('does not render in FPT because feature is not available in FPT', async () => {
req.context = {
currentVersion: 'free-pro-team@latest',
page: {},
page: {} as Page, // it just has to be any truthy value
allVersions,
enterpriseServerReleases,
}
await featureVersionsMiddleware(req, null, () => {})
const outputFpt = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(outputFpt.includes('placeholder content')).toBe(false)
} as Context
featureVersionsMiddleware(req as ExtendedRequest, {} as Response, () => {})
const output = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(output.includes('placeholder content')).toBe(false)
})

test('renders in GHES because feature is available in GHES', async () => {
req.context = {
currentVersion: `enterprise-server@${enterpriseServerReleases.latest}`,
page: {},
page: {} as Page, // it just has to be any truthy value
allVersions,
enterpriseServerReleases,
}
await featureVersionsMiddleware(req, null, () => {})
const outputFpt = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(outputFpt.includes('placeholder content')).toBe(true)
} as Context
featureVersionsMiddleware(req, {} as Response, () => {})
const output = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(output.includes('placeholder content')).toBe(true)
})

test('renders in GHEC because feature is available in GHEC', async () => {
req.context = {
currentVersion: 'enterprise-cloud@latest',
page: {},
page: {} as Page, // it just has to be any truthy value
allVersions,
enterpriseServerReleases,
}
await featureVersionsMiddleware(req, null, () => {})
const outputFpt = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(outputFpt.includes('placeholder content')).toBe(true)
} as Context
featureVersionsMiddleware(req, {} as Response, () => {})
const output = await liquid.parseAndRender(featureVersionsTemplate, req.context)
expect(output.includes('placeholder content')).toBe(true)
})
})
})
1 change: 0 additions & 1 deletion src/frame/middleware/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export default async function contextualize(

const context: Context = {}
req.context = context
console.log('CREATING CONTEXT')

req.context.process = { env: {} }

Expand Down
2 changes: 1 addition & 1 deletion src/frame/middleware/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import genericToc from './context/generic-toc'
import breadcrumbs from './context/breadcrumbs'
import glossaries from './context/glossaries'
import renderProductName from './context/render-product-name'
import features from '@/versions/middleware/features.js'
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'
Expand Down
2 changes: 1 addition & 1 deletion src/links/lib/validate-docs-urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ async function renderInnerHTML(page: Page, permalink: Permalink) {
await contextualize(req as ExtendedRequest, res as Response, next)
await shortVersions(req, res, next)
await findPage(req, res, next)
await features(req, res, next)
features(req as ExtendedRequest, res as Response, next)

const markdown = await liquid.parseAndRender(page.markdown, req.context)
const processor = createMinimalProcessor(req.context)
Expand Down
4 changes: 1 addition & 3 deletions src/links/scripts/rendered-content-link-checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ type LinkFlaw = {
flaw: Flaw
}

// type Core = CoreInject

type Redirects = Record<string, string>
type PageMap = Record<string, Page>

Expand Down Expand Up @@ -1313,7 +1311,7 @@ async function renderInnerHTML(page: Page, permalink: Permalink) {
await contextualize(req as ExtendedRequest, res as Response, next)
await shortVersions(req, res, next)
req.context.page = page
await features(req, res, next)
features(req as ExtendedRequest, res as Response, next)

req.context.relativePath = page.relativePath

Expand Down
2 changes: 1 addition & 1 deletion src/pageinfo/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export async function getPageInfo(page: Page, pathname: string) {
await contextualize(renderingReq as ExtendedRequest, res as Response, next)
await shortVersions(renderingReq, res, next)
renderingReq.context.page = page
await features(renderingReq, res, next)
features(renderingReq as ExtendedRequest, res as Response, next)
const context = renderingReq.context

const title = await page.renderProp('title', context, { textOnly: true })
Expand Down
6 changes: 5 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ type Redirects = {
[key: string]: string
}

export type Context = {
type Features = {
[feature: string]: boolean
}

export type Context = Features & {
currentCategory?: string
error?: Error
siteTree?: SiteTree
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
import path from 'path'
import type { Response, NextFunction } from 'express'

import { ROOT } from '#src/frame/lib/constants.js'
import getApplicableVersions from '#src/versions/lib/get-applicable-versions.js'
import { getDeepDataByLanguage } from '#src/data-directory/lib/get-data.js'
import type { ExtendedRequest, FrontmatterVersions } from '@/types'
import { ROOT } from '@/frame/lib/constants.js'
import getApplicableVersions from '@/versions/lib/get-applicable-versions.js'
import { getDeepDataByLanguage } from '@/data-directory/lib/get-data.js'

export default function features(req, res, next) {
export default function features(req: ExtendedRequest, res: Response, next: NextFunction) {
if (!req.context) throw new Error('request is not contextualized')
if (!req.context.page) return next()

if (!req.context.currentVersion) throw new Error('currentVersion is not contextualized')
Object.entries(getFeaturesByVersion(req.context.currentVersion)).forEach(
([featureName, isFeatureAvailableInCurrentVersion]) => {
if (!req.context) throw new Error('request is not contextualized')
req.context[featureName] = isFeatureAvailableInCurrentVersion
},
)

return next()
}

let allFeatures
type FeatureVersions = {
versions: FrontmatterVersions
}

let allFeatures: Record<string, FeatureVersions>

const cache = new Map()
function getFeaturesByVersion(currentVersion) {
function getFeaturesByVersion(currentVersion: string): Record<string, boolean> {
if (!cache.has(currentVersion)) {
if (!allFeatures) {
// As of Oct 2022, the `data/features/**` reading is *not* JIT.
// The `data/features` is deliberately not ignored in nodemon.json.
// See internal issue #2389
allFeatures = getDeepDataByLanguage('features', 'en')
allFeatures = getDeepDataByLanguage('features', 'en') as Record<string, FeatureVersions>
}

const features = {}
const features: {
[feature: string]: boolean
} = {}
// Determine whether the currentVersion belongs to the list of versions the feature is available in.
for (const [featureName, feature] of Object.entries(allFeatures)) {
const { versions } = feature
Expand Down

0 comments on commit 0375507

Please sign in to comment.