Skip to content

Commit 4403b4f

Browse files
heiskrCopilot
andauthored
⚙️ Remove any types from 6 files (#61089)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c4901b5 commit 4403b4f

8 files changed

Lines changed: 87 additions & 50 deletions

File tree

eslint.config.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,10 @@ export default [
225225
// Legacy files with @typescript-eslint/no-explicit-any violations (see github/docs-engineering#5797)
226226
{
227227
files: [
228-
'src/article-api/scripts/generate-api-docs.ts',
229228
'src/article-api/transformers/audit-logs-transformer.ts',
230229
'src/article-api/transformers/rest-transformer.ts',
231230
'src/codeql-cli/scripts/convert-markdown-for-docs.ts',
232231
'src/content-linter/scripts/lint-content.ts',
233-
234232
'src/content-render/liquid/index.ts',
235233
'src/content-render/scripts/liquid-tags.ts',
236234
'src/content-render/scripts/move-content.ts',
@@ -248,11 +246,8 @@ export default [
248246
'src/graphql/scripts/utils/schema-helpers.ts',
249247
'src/graphql/tests/validate-schema.ts',
250248
'src/landings/components/CookBookFilter.tsx',
251-
'src/landings/components/SidebarProduct.tsx',
252-
'src/landings/pages/product.tsx',
253249
'src/languages/lib/correct-translation-content.ts',
254250
'src/languages/lib/render-with-fallback.ts',
255-
'src/languages/lib/translation-utils.ts',
256251
'src/links/lib/update-internal-links.ts',
257252
'src/links/scripts/check-github-github-links.ts',
258253
'src/rest/components/get-rest-code-samples.ts',
@@ -266,20 +261,16 @@ export default [
266261
'src/rest/scripts/utils/update-markdown.ts',
267262
'src/rest/tests/get-rest-code-samples-2.ts',
268263
'src/rest/tests/get-rest-code-samples.ts',
269-
'src/rest/tests/openapi-schema.ts',
270264
'src/rest/tests/rendering.ts',
271265
'src/search/components/hooks/useAISearchAutocomplete.ts',
272266
'src/search/components/hooks/useAISearchLocalStorageCache.ts',
273-
'src/search/components/input/AskAIResults.tsx',
274267
'src/search/components/input/SearchOverlay.tsx',
275268
'src/search/lib/get-elasticsearch-results/ai-search-autocomplete.ts',
276269
'src/search/lib/get-elasticsearch-results/general-search.ts',
277270
'src/search/lib/routes/combined-search-route.ts',
278271
'src/search/lib/search-request-params/get-search-from-request-params.ts',
279-
'src/search/middleware/search-routes.ts',
280272
'src/search/scripts/index/index-cli.ts',
281273
'src/search/scripts/index/utils/indexing-elasticsearch-utils.ts',
282-
'src/search/scripts/scrape/lib/parse-page-sections-into-records.ts',
283274
'src/tests/helpers/check-url.ts',
284275
'src/tests/scripts/copy-fixture-data.ts',
285276
'src/tests/vitest.setup.ts',

src/article-api/scripts/generate-api-docs.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import { writeFileSync, readFileSync, existsSync } from 'fs'
22

3+
type ApiDoc = {
4+
method: string
5+
path: string
6+
description: string
7+
params: string[]
8+
returns: string
9+
examples: string
10+
throws: string[]
11+
}
12+
313
function main({ sources, outputPath }: { sources: string[]; outputPath: string }): void {
414
// Extract API documentation comments from all source files
515
const allDocs = sources.flatMap((sourcePath) => extractApiDocs(sourcePath))
@@ -14,8 +24,8 @@ function main({ sources, outputPath }: { sources: string[]; outputPath: string }
1424
}
1525

1626
// Extract API docs from comments in the file
17-
function extractApiDocs(file: string): string[] {
18-
const apiDocs: any[] = []
27+
function extractApiDocs(file: string): ApiDoc[] {
28+
const apiDocs: ApiDoc[] = []
1929

2030
// get the content from the api routes
2131
const content = readFileSync(file, 'utf8')
@@ -114,7 +124,7 @@ function extractExample(commentBlock: string): string {
114124
}
115125

116126
// Generate markdown from parsed documentation
117-
function generateMarkdown(apiDocs: any[]): string {
127+
function generateMarkdown(apiDocs: ApiDoc[]): string {
118128
let markdown = '## Reference: API endpoints\n\n'
119129

120130
for (const doc of apiDocs) {

src/landings/components/SidebarProduct.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Link from 'next/link'
22
import { useRouter } from 'next/router'
3-
import { useEffect, useState } from 'react'
3+
import React, { useEffect, useState } from 'react'
44
import { NavList } from '@primer/react'
55

66
import { ProductTreeNode, useMainContext } from '@/frame/components/context/MainContext'
@@ -172,8 +172,8 @@ function RestNavListItem({ category }: { category: ProductTreeNode }) {
172172
<NavList.Item
173173
defaultOpen={routePath.includes(childPage.href)}
174174
key={childPage.href}
175-
// Using any because Primer React's NavList doesn't export proper event types
176-
onClick={(event: any) => {
175+
// Using React.MouseEvent because Primer React's NavList doesn't export proper event types
176+
onClick={(event: React.MouseEvent<HTMLElement>) => {
177177
event.preventDefault()
178178
push(childPage.href)
179179
}}

src/landings/pages/product.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { useEffect } from 'react'
22
import { GetServerSideProps } from 'next'
3+
import type { Response } from 'express'
34
import { useRouter } from 'next/router'
45

6+
import type { ExtendedRequest } from '@/types'
7+
import type { JourneyTrack } from '@/journeys/lib/journey-path-resolver'
8+
59
// "legacy" javascript needed to maintain existing functionality
610
// typically operating on elements **within** an article.
711
import copyCode from '@/frame/components/lib/copy-code'
@@ -132,8 +136,8 @@ const GlobalPage = ({
132136
export default GlobalPage
133137

134138
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
135-
const req = context.req as any
136-
const res = context.res as any
139+
const req = context.req as unknown as ExtendedRequest
140+
const res = context.res as unknown as Response
137141

138142
const props: Props = {
139143
mainContext: await getMainContext(req, res),
@@ -151,8 +155,9 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
151155

152156
// journey tracks are resolved in middleware and added to the request
153157
// so we need to add them to the journey context here
154-
if ((req.context.page as any).resolvedJourneyTracks) {
155-
props.journeyContext.journeyTracks = (req.context.page as any).resolvedJourneyTracks
158+
const page = req.context?.page as { resolvedJourneyTracks?: JourneyTrack[] } | undefined
159+
if (page?.resolvedJourneyTracks) {
160+
props.journeyContext.journeyTracks = page.resolvedJourneyTracks
156161
}
157162

158163
additionalUINamespaces.push('journey_landing', 'product_landing')
@@ -161,15 +166,21 @@ export const getServerSideProps: GetServerSideProps<Props> = async (context) =>
161166
additionalUINamespaces.push('product_landing', 'carousels')
162167
} else if (relativePath?.endsWith('index.md')) {
163168
if (currentLayoutName === 'category-landing') {
164-
props.categoryLandingContext = getCategoryLandingContextFromRequest(req)
169+
props.categoryLandingContext = getCategoryLandingContextFromRequest(
170+
req as unknown as Parameters<typeof getCategoryLandingContextFromRequest>[0],
171+
)
165172
} else {
166-
props.tocLandingContext = getTocLandingContextFromRequest(req)
173+
props.tocLandingContext = getTocLandingContextFromRequest(
174+
req as unknown as Parameters<typeof getTocLandingContextFromRequest>[0],
175+
)
167176
}
168177
} else if (props.mainContext.page) {
169178
// All articles that might have hover cards needs this
170179
additionalUINamespaces.push('popovers')
171180

172-
props.articleContext = getArticleContextFromRequest(req)
181+
props.articleContext = getArticleContextFromRequest(
182+
req as unknown as Parameters<typeof getArticleContextFromRequest>[0],
183+
)
173184
if (props.articleContext.currentJourneyTrack?.trackId) {
174185
additionalUINamespaces.push('journey_track_nav')
175186
}

src/languages/lib/translation-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export function createTranslationFunctions(uiData: UIStrings, namespaces: string
8787
return {} as UIStrings
8888
}
8989
},
90-
t: (strings: TemplateStringsArray | string, ...values: Array<any>) => {
90+
t: (strings: TemplateStringsArray | string, ...values: Array<unknown>) => {
9191
const key = typeof strings === 'string' ? strings : String.raw(strings, ...values)
9292
// Provide specific fallbacks for common 404 page keys
9393
const commonFallbacks: Record<string, string> = {

src/rest/tests/openapi-schema.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import walk from 'walk-sync'
55
import { isPlainObject, difference } from 'lodash-es'
66

77
import { isApiVersioned, allVersions } from '@/versions/lib/all-versions'
8-
import getRest, { getRestCategories } from '../lib/index'
8+
import getRest, { getRestCategories, type RestOperationCategory } from '../lib/index'
99
import readFrontmatter from '@/frame/lib/read-frontmatter'
1010
import frontmatter from '@/frame/lib/frontmatter'
1111
import getApplicableVersions from '../../versions/lib/get-applicable-versions'
1212
import { getAutomatedMarkdownFiles } from '../scripts/test-open-api-schema'
1313
import { nonAutomatedRestPaths } from '../lib/config'
14+
import type { Operation } from '@/rest/components/types'
1415

1516
const schemasPath = 'src/rest/data'
1617

17-
// Operations have dynamic structure from OpenAPI schema - using any to avoid complex type definitions
18-
async function getFlatListOfOperations(version: string): Promise<any[]> {
19-
const flatList = []
18+
async function getFlatListOfOperations(version: string): Promise<Operation[]> {
19+
const flatList: Operation[] = []
2020

2121
if (isApiVersioned(version)) {
2222
for (const apiVersion of allVersions[version].apiVersions) {
@@ -38,16 +38,17 @@ async function getFlatListOfOperations(version: string): Promise<any[]> {
3838
describe('markdown for each rest version', () => {
3939
// Unique set of all categories across all versions of the OpenAPI schema
4040
const allCategories = new Set<string>()
41-
// Entire schema including categories and subcategories - using any due to dynamic OpenAPI structure
42-
const openApiSchema: Record<string, any> = {}
41+
// Entire schema including categories and subcategories, keyed by version then category
42+
const openApiSchema: Record<string, Record<string, RestOperationCategory>> = {}
4343
// All applicable version of categories based on frontmatter in the categories index.md file
44-
const categoryApplicableVersions: Record<string, any> = {}
44+
const categoryApplicableVersions: Record<string, string[]> = {}
4545

4646
function getApplicableVersionFromFile(file: string) {
4747
const currentFile = fs.readFileSync(file, 'utf8')
48-
// Frontmatter data structure is dynamic based on file content
49-
const { data } = frontmatter(currentFile) as { data: any }
50-
return getApplicableVersions(data.versions, file)
48+
const fm = frontmatter(currentFile) as unknown as {
49+
data?: { versions?: string | Record<string, string | string[]> }
50+
}
51+
return getApplicableVersions(fm.data?.versions, file)
5152
}
5253

5354
function getCategorySubcategory(file: string) {
@@ -127,12 +128,15 @@ describe('markdown for each rest version', () => {
127128
describe('rest file structure', () => {
128129
test('children of content/rest/index.md are in alphabetical order', async () => {
129130
const indexContent = fs.readFileSync('content/rest/index.md', 'utf8')
130-
// Frontmatter data structure is dynamic based on file content
131-
const { data } = readFrontmatter(indexContent) as { data: any }
131+
const fm = readFrontmatter(indexContent) as unknown as {
132+
data?: { children?: string[] }
133+
}
134+
const children = fm.data?.children
135+
expect(Array.isArray(children)).toBe(true)
132136
const nonAutomatedChildren = nonAutomatedRestPaths.map((child: string) =>
133137
child.replace('/rest', ''),
134138
)
135-
const sortableChildren = data.children.filter(
139+
const sortableChildren = (children as string[]).filter(
136140
(child: string) => !nonAutomatedChildren.includes(child),
137141
)
138142
expect(sortableChildren).toStrictEqual([...sortableChildren].sort())
@@ -203,11 +207,12 @@ describe('code examples are defined', () => {
203207
}
204208

205209
const operation = await findOperation(version, 'GET', '/repos/{owner}/{repo}')
210+
expect(operation).toBeDefined()
211+
if (!operation) continue
206212
expect(operation.serverUrl).toBe(domain)
207213
expect(isPlainObject(operation)).toBe(true)
208214
expect(operation.codeExamples).toBeDefined()
209-
// Code examples have dynamic structure from OpenAPI schema
210-
for (const example of operation.codeExamples as any[]) {
215+
for (const example of operation.codeExamples) {
211216
expect(isPlainObject(example.request)).toBe(true)
212217
expect(isPlainObject(example.response)).toBe(true)
213218
}

src/search/components/input/AskAIResults.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,20 @@ export function AskAIResults({
235235
let leftover = '' // <= carry‑over buffer
236236
setInitialLoading(false)
237237

238-
const processLine = (parsedLine: any) => {
238+
type ParsedLine = {
239+
chunkType?: string
240+
conversation_id?: string
241+
sources?: AIReference[]
242+
text?: string
243+
errors?: unknown
244+
}
245+
246+
const processLine = (parsedLine: ParsedLine) => {
239247
switch (parsedLine.chunkType) {
240248
// A conversation ID will still be sent when a question cannot be answered
241249
case 'CONVERSATION_ID':
242-
conversationIdBuffer = parsedLine.conversation_id
243-
setConversationId(parsedLine.conversation_id)
250+
conversationIdBuffer = parsedLine.conversation_id ?? ''
251+
setConversationId(parsedLine.conversation_id ?? '')
244252
break
245253

246254
case 'NO_CONTENT_SIGNAL':
@@ -251,7 +259,7 @@ export function AskAIResults({
251259
case 'SOURCES':
252260
if (!isCancelled) {
253261
sourcesBuffer = uniqBy(
254-
sourcesBuffer.concat(parsedLine.sources as AIReference[]),
262+
sourcesBuffer.concat((parsedLine.sources ?? []) as AIReference[]),
255263
'url',
256264
)
257265
setReferences(sourcesBuffer)
@@ -260,7 +268,7 @@ export function AskAIResults({
260268

261269
case 'MESSAGE_CHUNK':
262270
if (!isCancelled) {
263-
messageBuffer += parsedLine.text
271+
messageBuffer += parsedLine.text ?? ''
264272
setMessage(messageBuffer)
265273
}
266274
break
@@ -298,7 +306,7 @@ export function AskAIResults({
298306
for (const raw of lines) {
299307
if (!raw.trim()) continue
300308

301-
let parsedLine: any
309+
let parsedLine: ParsedLine
302310
try {
303311
parsedLine = JSON.parse(raw)
304312
if (parsedLine?.errors) {
@@ -331,7 +339,7 @@ export function AskAIResults({
331339
console.warn('Failed to parse tail JSON:', leftover, err)
332340
}
333341
}
334-
} catch (error: any) {
342+
} catch (error: unknown) {
335343
if (!isCancelled) {
336344
console.error('Failed to fetch search results:', error)
337345
setAISearchError()

src/search/middleware/search-routes.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,35 @@ router.get('/combined-search/v1', catchMiddlewareError(combinedSearchRoute))
3030
export async function handleGetSearchResultsError(
3131
req: Request,
3232
res: Response,
33-
error: any,
34-
options: any,
33+
error: unknown,
34+
options: unknown,
3535
) {
36+
const errorMessage = error instanceof Error ? error.message : String(error)
3637
if (process.env.NODE_ENV === 'development') {
3738
console.error(`Error calling getSearchResults(${options})`, error)
3839
} else {
39-
const reports = FailBot.report(error, { url: req.url, ...options })
40+
const extra: Record<string, unknown> =
41+
options && typeof options === 'object' && !Array.isArray(options)
42+
? Object.fromEntries(
43+
Object.entries(options as Record<string, unknown>).map(([k, v]) => [
44+
k,
45+
v && typeof v === 'object' ? JSON.stringify(v) : v,
46+
]),
47+
)
48+
: { options: typeof options === 'object' ? JSON.stringify(options) : options }
49+
extra.url = req.url
50+
const errorForReport = error instanceof Error ? error : new Error(errorMessage)
51+
const reports = FailBot.report(errorForReport, extra)
4052
if (reports) await Promise.all(reports)
4153
}
4254
// Avoid "Cannot set headers after they are sent to the client" error
4355
// if response was already partially sent before the error occurred
4456
if (!res.headersSent) {
45-
res.status(500).json({ error: error.message })
57+
res.status(500).json({ error: errorMessage })
4658
} else {
4759
logger.warn('Response headers already sent; unable to send error response.', {
4860
url: req.url,
49-
message: error?.message,
61+
message: errorMessage,
5062
})
5163
}
5264
}

0 commit comments

Comments
 (0)