Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export default [
'rest-api-description/',
'docs-internal-data/',
'src/code-scanning/scripts/generate-code-scanning-query-list.ts',
'next-env.d.ts',
],
},

Expand Down
3 changes: 2 additions & 1 deletion src/app/lib/app-router-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { getUIDataMerged } from '@/data-directory/lib/get-data'
import { type LanguageCode } from '@/languages/lib/languages'
import { translate } from '@/languages/lib/translation-utils'
import { extractLanguageFromPath } from '@/app/lib/language-utils'
import { type UIStrings } from '@/frame/components/context/MainContext'

export interface AppRouterContext {
currentLanguage: LanguageCode
currentVersion: string
sitename: string
site: {
data: {
ui: any
ui: UIStrings
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/article-api/middleware/article-pageinfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export async function getPageInfoFromCache(page: Page, pathname: string) {
cacheInfo = 'initial-load'
} catch (error) {
cacheInfo = 'initial-fail'
if (error instanceof Error && (error as any).code !== 'ENOENT') {
if (error instanceof Error && (error as NodeJS.ErrnoException).code !== 'ENOENT') {
throw error
}
_cache = {}
Expand Down
62 changes: 46 additions & 16 deletions src/assets/tests/static-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import path from 'path'

import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'
import nock from 'nock'
import type { Response } from 'express'

import { get } from '@/tests/helpers/e2etest'
import { checkCachingHeaders } from '@/tests/helpers/caching-headers'
import { setDefaultFastlySurrogateKey } from '@/frame/middleware/set-fastly-surrogate-key'
import archivedEnterpriseVersionsAssets from '@/archives/middleware/archived-enterprise-versions-assets'
import type { ExtendedRequest } from '@/types'

function getNextStaticAsset(directory: string) {
const root = path.join('.next', 'static', directory)
Expand All @@ -34,10 +36,10 @@ function mockRequest(requestPath: string, { headers }: { headers?: Record<string
}

type MockResponse = {
status: number
statusCode: number
json?: (payload: any) => void
send?: (body: any) => void
status: number | undefined
statusCode: number | undefined
json?: (payload: unknown) => void
send?: (body: unknown) => void
sendStatus?: (statusCode: number) => void
end?: () => void
_json?: string
Expand All @@ -50,17 +52,17 @@ type MockResponse = {

const mockResponse = () => {
const res: MockResponse = {
status: undefined as any,
statusCode: undefined as any,
status: undefined,
statusCode: undefined,
headers: {},
}
res.json = (payload) => {
res._json = payload
res._json = payload as string
}
res.send = (body) => {
res.status = 200
res.statusCode = 200
res._send = body
res._send = body as string
}
res.end = () => {
// Mock end method
Expand All @@ -86,7 +88,7 @@ const mockResponse = () => {
return key in res.headers
}
// Add Express-style status method that supports chaining
;(res as any).status = (code: number) => {
;(res as unknown as { status: (code: number) => MockResponse }).status = (code: number) => {
res.status = code
res.statusCode = code
return res
Expand Down Expand Up @@ -222,7 +224,11 @@ describe('archived enterprise static assets', () => {
throw new Error('did not expect this to ever happen')
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, false, 60)
})
Expand All @@ -238,7 +244,11 @@ describe('archived enterprise static assets', () => {
throw new Error('did not expect this to ever happen')
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, false, 60)
})
Expand All @@ -254,7 +264,11 @@ describe('archived enterprise static assets', () => {
throw new Error('did not expect this to ever happen')
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, false, 60)
})
Expand All @@ -271,7 +285,11 @@ describe('archived enterprise static assets', () => {
nexted = true
}
setDefaultFastlySurrogateKey(req, res, next)
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
// It didn't exit in that middleware but called next() to move on
// with any other middlewares.
expect(nexted).toBe(true)
Expand All @@ -289,7 +307,11 @@ describe('archived enterprise static assets', () => {
nexted = true
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
// It tried to go via the proxy, but it wasn't there, but then it
// tried "our disk" and it's eventually there.
expect(nexted).toBe(true)
Expand Down Expand Up @@ -335,7 +357,11 @@ describe('archived enterprise static assets', () => {
nexted = true
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
expect(res.statusCode).toBe(expectStatus)
if (shouldCallNext) {
expect(nexted).toBe(true)
Expand Down Expand Up @@ -374,7 +400,11 @@ describe('archived enterprise static assets', () => {
nexted = true
}
setDefaultFastlySurrogateKey(req, res, () => {})
await archivedEnterpriseVersionsAssets(req as any, res as any, next)
await archivedEnterpriseVersionsAssets(
req as unknown as ExtendedRequest,
res as unknown as Response,
next,
)
expect(nexted).toBe(shouldCallNext)
expect(res.statusCode).toBe(expectStatus)
})
Expand Down
7 changes: 4 additions & 3 deletions src/audit-logs/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path'
import { readCompressedJsonFileFallback } from '@/frame/lib/read-json-file'
import { getOpenApiVersion } from '@/versions/lib/all-versions'
import findPage from '@/frame/lib/find-page'
import type { Context, Page } from '@/types'
import type {
AuditLogEventT,
CategorizedEvents,
Expand Down Expand Up @@ -30,8 +31,8 @@ export function getCategoryNotes(): CategoryNotes {
return auditLogConfig.categoryNotes || {}
}

type TitleResolutionContext = {
pages: Record<string, any>
type TitleResolutionContext = Context & {
pages: Record<string, Page>
redirects: Record<string, string>
}

Expand Down Expand Up @@ -61,7 +62,7 @@ async function resolveReferenceLinksToTitles(
currentVersion: 'free-pro-team@latest',
pages: context.pages,
redirects: context.redirects,
}
} as unknown as Context
const title = await page.renderProp('title', renderContext, { textOnly: true })
titles.push(title)
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/automated-pipelines/lib/update-markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { MarkdownFrontmatter } from '@/types'
// Type definitions - extending existing type to add missing fields and make most fields optional
type FrontmatterData = Partial<MarkdownFrontmatter> & {
autogenerated?: string
[key: string]: any
[key: string]: unknown
}

type SourceContentItem = {
Expand Down
6 changes: 3 additions & 3 deletions src/content-linter/lib/helpers/get-rules.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { gitHubDocsMarkdownlint } from '@/content-linter/lib/linting-rules/index'
import { baseConfig } from '@/content-linter/style/base'
import { customConfig } from '@/content-linter/style/github-docs'
import type { Rule } from '@/content-linter/types'
import type { Rule, RuleConfig } from '@/content-linter/types'

// Import markdownlint rules - external library without TypeScript declarations
import markdownlintRules from '../../../../node_modules/markdownlint/lib/rules'

export const customRules: Rule[] = gitHubDocsMarkdownlint.rules
export const allRules: any[] = [...markdownlintRules, ...gitHubDocsMarkdownlint.rules]
export const allConfig: Record<string, any> = { ...baseConfig, ...customConfig }
export const allRules: Rule[] = [...markdownlintRules, ...gitHubDocsMarkdownlint.rules]
export const allConfig = { ...baseConfig, ...customConfig } as unknown as RuleConfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { RuleParams, RuleErrorCallback, Rule } from '@/content-linter/types
interface Frontmatter {
redirect_from?: string | string[]
children?: string[]
[key: string]: any
[key: string]: unknown
}

const ERROR_MESSAGE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { RuleParams, RuleErrorCallback, Rule } from '@/content-linter/types

interface Frontmatter {
heroImage?: string
[key: string]: any
[key: string]: unknown
}

// Get the list of valid hero images (without extensions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { RuleParams, RuleErrorCallback, Rule } from '@/content-linter/types

interface Frontmatter {
introLinks?: Record<string, string>
[key: string]: any
[key: string]: unknown
}

// Get the valid introLinks keys from ui.yml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import { addError } from 'markdownlint-rule-helpers'
import { getFrontmatter } from '../helpers/utils'
import type { RuleParams, RuleErrorCallback } from '@/content-linter/types'

interface Frontmatter {
recommended?: string[]
layout?: string
[key: string]: unknown
}

function isValidArticlePath(articlePath: string, currentFilePath: string): boolean {
const ROOT = process.env.ROOT || '.'

Expand Down Expand Up @@ -53,7 +59,7 @@ export const frontmatterLandingRecommended = {
tags: ['frontmatter', 'landing', 'recommended'],
function: (params: RuleParams, onError: RuleErrorCallback) => {
// Using any for frontmatter as it's a dynamic YAML object with varying properties
const fm: any = getFrontmatter(params.lines)
const fm = getFrontmatter(params.lines) as Frontmatter | null
if (!fm || !fm.recommended) return

const recommendedLine: string | undefined = params.lines.find((line) =>
Expand Down
4 changes: 3 additions & 1 deletion src/content-linter/lib/linting-rules/frontmatter-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export const frontmatterSchema: Rule = {

// Check that the frontmatter matches the schema
const { errors } = readFrontmatter(params.lines.join('\n'), { schema: frontmatter.schema })
const formattedErrors = formatAjvErrors(errors as any)
const formattedErrors = formatAjvErrors(
errors as unknown as Parameters<typeof formatAjvErrors>[0],
)
for (const error of formattedErrors) {
// If the missing property is at the top level, we don't have a line
// to point to. In that case, the error will be added to line 1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { RuleParams, RuleErrorCallback, Rule } from '@/content-linter/types

interface Frontmatter {
versions?: Record<string, string | string[]>
[key: string]: any
[key: string]: unknown
}

export const frontmatterVersionsWhitespace: Rule = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface Frontmatter {
product_video_transcript?: string
title?: string
layout?: string
[key: string]: any
[key: string]: unknown
}

export const frontmatterVideoTranscripts: Rule = {
Expand Down
1 change: 1 addition & 0 deletions src/content-linter/scripts/lint-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ function getMarkdownLintConfig(
const ymlSearchReplaceRules = []
const frontmatterSearchReplaceRules = []

if (!ruleConfig.rules) continue
for (const searchRule of ruleConfig.rules) {
const searchRuleSeverity = getSeverity(searchRule, isPrecommit)
if (filterErrorsOnly && searchRuleSeverity !== 'error') continue
Expand Down
7 changes: 5 additions & 2 deletions src/content-linter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface RuleParams {
frontMatterLines: string[] // array of frontmatter lines
tokens?: MarkdownToken[] // markdown tokens (when using markdownit parser)
config?: {
[key: string]: any // rule-specific configuration
[key: string]: unknown // rule-specific configuration
}
}

Expand All @@ -26,7 +26,7 @@ export interface RuleErrorCallback {
detail?: string,
context?: string,
range?: [number, number],
fixInfo?: any,
fixInfo?: unknown,
): void
}

Expand All @@ -44,6 +44,8 @@ export type Rule = {
type RuleDetail = Rule & {
name: string
'partial-markdown-files': boolean
'yml-files'?: boolean
applyToFrontmatter?: boolean
message: string
severity: string
searchPattern: string
Expand All @@ -54,6 +56,7 @@ type RuleDetail = Rule & {
export type Config = {
severity: string
'partial-markdown-files': boolean
'yml-files'?: boolean
allowed_languages?: string[]
style?: string
rules?: RuleDetail[]
Expand Down
3 changes: 2 additions & 1 deletion src/frame/middleware/categories-for-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ export default async function categoriesForSupport(req: ExtendedRequest, res: Re
// We can't get the rendered titles from middleware/render-tree-titles
// here because that middleware only runs on the current version, and this
// middleware processes all versions.
if (!req.context) return
const name = categoryPage.page.title.includes('{')
? await categoryPage.page.renderProp('title', req.context, renderOpts)
: categoryPage.page.title

allCategories.push({
name,
published_articles: await findArticlesPerCategory(categoryPage, [], req.context!),
published_articles: await findArticlesPerCategory(categoryPage, [], req.context),
})
}),
)
Expand Down
2 changes: 1 addition & 1 deletion src/frame/middleware/render-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default async function renderPage(req: ExtendedRequest, res: Response) {
req.context.currentVersion === 'free-pro-team@latest' ||
!allVersions[req.context.currentVersion!]
) {
page.fullTitle += ` - ${context.site!.data.ui.header.github_docs}`
page.fullTitle += ` - ${get(context.site!.data.ui, 'header.github_docs')}`
} else {
const { versionTitle } = allVersions[req.context.currentVersion!]
page.fullTitle += ' - '
Expand Down
Loading