Skip to content

Commit fac4a0e

Browse files
authored
Migrate 15 JavaScript files to TypeScript (#57875)
1 parent f5df15a commit fac4a0e

File tree

17 files changed

+170
-97
lines changed

17 files changed

+170
-97
lines changed

src/content-linter/scripts/disable-rules.js renamed to src/content-linter/scripts/disable-rules.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import fs from 'fs'
1010
import { spawn } from 'child_process'
1111

12-
const rule = process.argv[2]
12+
const rule: string | undefined = process.argv[2]
1313
if (!rule) {
1414
console.error('Please specify a rule to disable.')
1515
process.exit(1)
@@ -38,36 +38,40 @@ const childProcess = spawn('npm', [
3838
rule,
3939
])
4040

41-
childProcess.stdout.on('data', (data) => {
41+
childProcess.stdout.on('data', (data: Buffer) => {
4242
if (verbose) console.log(data.toString())
4343
})
4444

45-
childProcess.stderr.on('data', function (data) {
45+
childProcess.stderr.on('data', function (data: Buffer) {
4646
if (verbose) console.log(data.toString())
4747
})
4848

4949
let matchingRulesFound = 0
50-
childProcess.on('close', (code) => {
50+
childProcess.on('close', (code: number | null) => {
5151
if (code === 0) {
5252
console.log(`No violations for rule, "${rule}" found.`)
5353
process.exit(0)
5454
}
5555

56-
const markdownViolations = JSON.parse(fs.readFileSync('markdown-violations.json', 'utf8'))
56+
const markdownViolations: Record<string, Array<{ lineNumber: number }>> = JSON.parse(
57+
fs.readFileSync('markdown-violations.json', 'utf8'),
58+
)
5759
console.log(`${Object.values(markdownViolations).flat().length} violations found.`)
5860

59-
Object.entries(markdownViolations).forEach(([fileName, results]) => {
60-
console.log(fileName)
61-
console.log(results)
62-
const fileLines = fs.readFileSync(fileName, 'utf8').split('\n')
63-
results.forEach((result) => {
64-
matchingRulesFound++
65-
const lineIndex = result.lineNumber - 1
66-
const offendingLine = fileLines[lineIndex]
67-
fileLines[lineIndex] = offendingLine.concat(` <!-- markdownlint-disable-line ${rule} -->`)
68-
})
69-
fs.writeFileSync(fileName, fileLines.join('\n'), 'utf8')
70-
})
61+
Object.entries(markdownViolations).forEach(
62+
([fileName, results]: [string, Array<{ lineNumber: number }>]) => {
63+
console.log(fileName)
64+
console.log(results)
65+
const fileLines = fs.readFileSync(fileName, 'utf8').split('\n')
66+
results.forEach((result) => {
67+
matchingRulesFound++
68+
const lineIndex = result.lineNumber - 1
69+
const offendingLine = fileLines[lineIndex]
70+
fileLines[lineIndex] = offendingLine.concat(` <!-- markdownlint-disable-line ${rule} -->`)
71+
})
72+
fs.writeFileSync(fileName, fileLines.join('\n'), 'utf8')
73+
},
74+
)
7175

7276
console.log(`${matchingRulesFound} violations ignored.`)
7377
})

src/content-linter/tests/unit/liquid-data-tags.js renamed to src/content-linter/tests/unit/liquid-data-tags.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import path from 'path'
33
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
44

55
import { runRule } from '../../lib/init-test'
6+
import type { Rule } from '@/content-linter/types'
67
import {
78
liquidDataReferencesDefined,
89
liquidDataTagFormat,
@@ -31,7 +32,7 @@ describe(liquidDataReferencesDefined.names.join(' - '), () => {
3132
'{% data ui.nested.nested.not-there %}',
3233
'{% data some.random.path %}',
3334
]
34-
const result = await runRule(liquidDataReferencesDefined, {
35+
const result = await runRule(liquidDataReferencesDefined as Rule, {
3536
strings: { markdown: markdown.join('\n') },
3637
})
3738
const errors = result.markdown
@@ -45,7 +46,7 @@ describe(liquidDataReferencesDefined.names.join(' - '), () => {
4546
'{% data variables.location.product_location %}',
4647
'{% data ui.header.notices.release_candidate %}',
4748
].join('\n')
48-
const result = await runRule(liquidDataReferencesDefined, { strings: { markdown } })
49+
const result = await runRule(liquidDataReferencesDefined as Rule, { strings: { markdown } })
4950
const errors = result.markdown
5051
expect(errors.length).toBe(0)
5152
})
@@ -57,7 +58,7 @@ describe(liquidDataReferencesDefined.names.join(' - '), () => {
5758
'{% data %}',
5859
'{% indented_data_reference %}',
5960
]
60-
const result = await runRule(liquidDataTagFormat, {
61+
const result = await runRule(liquidDataTagFormat as Rule, {
6162
strings: { markdown: markdown.join('\n') },
6263
})
6364
const errors = result.markdown
@@ -69,7 +70,7 @@ describe(liquidDataReferencesDefined.names.join(' - '), () => {
6970
'{% data ui.header.notices.release_candidate %}',
7071
'{% indented_data_reference ui.header.notices.release_candidate spaces=3 %}',
7172
]
72-
const result = await runRule(liquidDataTagFormat, {
73+
const result = await runRule(liquidDataTagFormat as Rule, {
7374
strings: { markdown: markdown.join('\n') },
7475
})
7576
const errors = result.markdown

src/content-render/scripts/render-content-markdown.js renamed to src/content-render/scripts/render-content-markdown.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { execSync } from 'child_process'
44

55
import { renderLiquid } from '@/content-render/liquid/index'
66
import shortVersionsMiddleware from '@/versions/middleware/short-versions'
7+
import type { ExtendedRequest } from '@/types'
78

89
const { loadPages } = await import('@/frame/lib/page-data.js')
910
const { allVersions } = await import('@/versions/lib/all-versions.js')
@@ -32,20 +33,20 @@ for (const page of pages) {
3233
console.log(`---\nStart: Creating directories for: ${page.relativePath}`)
3334
const dirnames = page.relativePath.substring(0, page.relativePath.lastIndexOf('/'))
3435

35-
fs.mkdirSync(`${contentCopilotDir}/${dirnames}`, { recursive: true }, (err) => {
36-
if (err) throw err
37-
})
36+
fs.mkdirSync(`${contentCopilotDir}/${dirnames}`, { recursive: true })
3837
// Context needed to render the content liquid
39-
const req = { language: 'en' }
40-
const contextualize = (req) => {
41-
req.context.currentVersionObj = req.context.allVersions[req.context.currentVersion]
38+
const req = { language: 'en' } as ExtendedRequest
39+
const contextualize = (req: ExtendedRequest): void => {
40+
if (!req.context) return
41+
if (!req.context.currentVersion) return
42+
req.context.currentVersionObj = req.context.allVersions?.[req.context.currentVersion]
4243
shortVersionsMiddleware(req, null, () => {})
4344
}
4445

4546
req.context = {
4647
currentLanguage: 'en',
4748
currentVersion: 'free-pro-team@latest',
48-
page: {},
49+
page: {} as any, // Empty page object used only for context initialization
4950
allVersions,
5051
}
5152
contextualize(req)
@@ -77,7 +78,8 @@ for (const page of pages) {
7778
'utf8',
7879
)
7980
console.log(`Done: written file\n---`)
80-
} catch (err) {
81+
} catch (err: any) {
82+
// Standard catch-all for error handling in scripts
8183
console.log(err)
8284
}
8385
}

src/content-render/unified/alerts.js renamed to src/content-render/unified/alerts.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ Custom "Alerts", based on similar filter/styling in the monolith code.
44

55
import { visit } from 'unist-util-visit'
66
import { h } from 'hastscript'
7+
// @ts-ignore - no types available for @primer/octicons
78
import octicons from '@primer/octicons'
9+
import type { Element } from 'hast'
810

9-
const alertTypes = {
11+
interface AlertType {
12+
icon: string
13+
color: string
14+
}
15+
16+
const alertTypes: Record<string, AlertType> = {
1017
NOTE: { icon: 'info', color: 'accent' },
1118
IMPORTANT: { icon: 'report', color: 'done' },
1219
WARNING: { icon: 'alert', color: 'attention' },
@@ -17,14 +24,17 @@ const alertTypes = {
1724
// Must contain one of [!NOTE], [!IMPORTANT], ...
1825
const ALERT_REGEXP = new RegExp(`\\[!(${Object.keys(alertTypes).join('|')})\\]`, 'gi')
1926

20-
const matcher = (node) =>
27+
// Using any due to conflicting unist/hast type definitions between dependencies
28+
const matcher = (node: any): boolean =>
2129
node.type === 'element' &&
2230
node.tagName === 'blockquote' &&
2331
ALERT_REGEXP.test(JSON.stringify(node.children))
2432

25-
export default function alerts({ alertTitles = {} }) {
26-
return (tree) => {
27-
visit(tree, matcher, (node) => {
33+
export default function alerts({ alertTitles = {} }: { alertTitles?: Record<string, string> }) {
34+
// Using any due to conflicting unist/hast type definitions between dependencies
35+
return (tree: any) => {
36+
// Using any due to conflicting unist/hast type definitions between dependencies
37+
visit(tree, matcher, (node: any) => {
2838
const key = getAlertKey(node)
2939
if (!(key in alertTypes)) {
3040
console.warn(
@@ -48,13 +58,14 @@ export default function alerts({ alertTitles = {} }) {
4858
}
4959
}
5060

51-
function getAlertKey(node) {
61+
function getAlertKey(node: Element): string {
5262
const body = JSON.stringify(node.children)
5363
const matches = body.match(ALERT_REGEXP)
54-
return matches[0].slice(2, -1)
64+
return matches![0].slice(2, -1)
5565
}
5666

57-
function removeAlertSyntax(node) {
67+
// Using any to handle both array and object node types recursively
68+
function removeAlertSyntax(node: any): any {
5869
if (Array.isArray(node)) {
5970
return node.map(removeAlertSyntax)
6071
}
@@ -67,7 +78,7 @@ function removeAlertSyntax(node) {
6778
return node
6879
}
6980

70-
function getOcticonSVG(name) {
81+
function getOcticonSVG(name: string): Element {
7182
return h(
7283
'svg',
7384
{
@@ -78,6 +89,6 @@ function getOcticonSVG(name) {
7889
className: 'octicon mr-2',
7990
ariaHidden: true,
8091
},
81-
h('path', { d: octicons[name].heights[16].path.match(/d="(.*)"/)[1] }),
92+
h('path', { d: octicons[name].heights[16].path.match(/d="(.*)"/)![1] }),
8293
)
8394
}

src/data-directory/lib/data-schemas/release-notes.js renamed to src/data-directory/lib/data-schemas/release-notes.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const section = {
3232
},
3333
},
3434
],
35-
}
35+
} as const
3636

3737
export default {
3838
type: 'object',
@@ -69,7 +69,10 @@ export default {
6969
'errata',
7070
'closing_down',
7171
'retired',
72-
].reduce((prev, curr) => ({ ...prev, [curr]: section }), {}),
72+
].reduce(
73+
(prev: Record<string, typeof section>, curr: string) => ({ ...prev, [curr]: section }),
74+
{},
75+
),
7376
},
7477
},
75-
}
78+
} as const

src/frame/lib/permalink.js renamed to src/frame/lib/permalink.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,20 @@ page.permalinks is an array of objects that looks like this:
2828
]
2929
*/
3030
class Permalink {
31-
constructor(languageCode, pageVersion, relativePath, title) {
31+
languageCode: string
32+
pageVersion: string
33+
relativePath: string
34+
title: string
35+
hrefWithoutLanguage: string
36+
href: string
37+
38+
constructor(languageCode: string, pageVersion: string, relativePath: string, title: string) {
3239
this.languageCode = languageCode
3340
this.pageVersion = pageVersion
3441
this.relativePath = relativePath
3542
this.title = title
3643

37-
const permalinkSuffix = this.constructor.relativePathToSuffix(relativePath)
44+
const permalinkSuffix = Permalink.relativePathToSuffix(relativePath)
3845

3946
this.hrefWithoutLanguage = removeFPTFromPath(
4047
path.posix.join('/', pageVersion, permalinkSuffix),
@@ -46,18 +53,23 @@ class Permalink {
4653
return this
4754
}
4855

49-
static derive(languageCode, relativePath, title, applicableVersions) {
56+
static derive(
57+
languageCode: string,
58+
relativePath: string,
59+
title: string,
60+
applicableVersions: string[],
61+
): Permalink[] {
5062
assert(relativePath, 'relativePath is required')
5163
assert(languageCode, 'languageCode is required')
5264

53-
const permalinks = applicableVersions.map((pageVersion) => {
65+
const permalinks = applicableVersions.map((pageVersion: string) => {
5466
return new Permalink(languageCode, pageVersion, relativePath, title)
5567
})
5668

5769
return permalinks
5870
}
5971

60-
static relativePathToSuffix(relativePath) {
72+
static relativePathToSuffix(relativePath: string): string {
6173
if (relativePath === 'index.md') return '/'
6274
// When you turn `foo/bar.md`, which is a file path, into a URL pathname,
6375
// you just need to chop off the `.md` suffix.

src/frame/lib/read-frontmatter.js renamed to src/frame/lib/read-frontmatter.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ import matter from '@gr2m/gray-matter'
22

33
import { validateJson } from '@/tests/lib/validate-json-schema'
44

5-
function readFrontmatter(markdown, opts = {}) {
5+
interface ReadFrontmatterOptions {
6+
schema?: Record<string, any> // Schema can have arbitrary properties for validation
7+
filepath?: string | null
8+
}
9+
10+
function readFrontmatter(markdown: string, opts: ReadFrontmatterOptions = {}) {
611
const schema = opts.schema || { type: 'object', properties: {} }
712
const filepath = opts.filepath || null
813

914
let content, data
1015

1116
try {
1217
;({ content, data } = matter(markdown))
13-
} catch (e) {
18+
} catch (e: any) {
1419
const defaultReason = 'invalid frontmatter entry'
1520

1621
const reason = e.reason
@@ -21,7 +26,7 @@ function readFrontmatter(markdown, opts = {}) {
2126
: e.reason
2227
: defaultReason
2328

24-
const error = {
29+
const error: any = {
2530
reason,
2631
message: 'YML parsing error!',
2732
}
@@ -33,7 +38,7 @@ function readFrontmatter(markdown, opts = {}) {
3338
return { errors }
3439
}
3540

36-
const validate = validateJson(schema, data)
41+
const validate: any = validateJson(schema, data)
3742

3843
// Combine the AJV-supplied `instancePath` and `params` into a more user-friendly frontmatter path.
3944
// For example, given:
@@ -44,7 +49,7 @@ function readFrontmatter(markdown, opts = {}) {
4449
//
4550
// The purpose is to help users understand that the error is on the `fpt` key within the `versions` object.
4651
// Note if the error is on a top-level FM property like `title`, the `instancePath` will be empty.
47-
const cleanPropertyPath = (params, instancePath) => {
52+
const cleanPropertyPath = (params: Record<string, any>, instancePath: string) => {
4853
const mainProps = Object.values(params)[0]
4954
if (!instancePath) return mainProps
5055

@@ -55,8 +60,8 @@ function readFrontmatter(markdown, opts = {}) {
5560
const errors = []
5661

5762
if (!validate.isValid && filepath) {
58-
const formattedErrors = validate.errors.map((error) => {
59-
const userFriendly = {}
63+
const formattedErrors = validate.errors.map((error: any) => {
64+
const userFriendly: any = {}
6065
userFriendly.property = cleanPropertyPath(error.params, error.instancePath)
6166
userFriendly.message = error.message
6267
userFriendly.reason = error.keyword

0 commit comments

Comments
 (0)