Skip to content

Commit 5268d1a

Browse files
authored
Migrate 8 JavaScript files to TypeScript (#57973)
1 parent f9f69b0 commit 5268d1a

File tree

10 files changed

+210
-87
lines changed

10 files changed

+210
-87
lines changed

src/content-linter/lib/linting-rules/note-warning-formatting.js renamed to src/content-linter/lib/linting-rules/note-warning-formatting.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
1+
// @ts-ignore - markdownlint-rule-helpers doesn't provide TypeScript declarations
12
import { addError } from 'markdownlint-rule-helpers'
23
import { getRange } from '../helpers/utils'
34
import frontmatter from '@/frame/lib/read-frontmatter'
5+
import type { RuleParams, RuleErrorCallback } from '@/content-linter/types'
6+
7+
interface NoteContentItem {
8+
text: string
9+
lineNumber: number
10+
}
411

512
export const noteWarningFormatting = {
613
names: ['GHD049', 'note-warning-formatting'],
714
description: 'Note and warning tags should be formatted according to style guide',
815
tags: ['formatting', 'callouts', 'notes', 'warnings', 'style'],
916
severity: 'warning',
10-
function: (params, onError) => {
17+
function: (params: RuleParams, onError: RuleErrorCallback) => {
1118
// Skip autogenerated files
1219
const frontmatterString = params.frontMatterLines.join('\n')
1320
const fm = frontmatter(frontmatterString).data
1421
if (fm && fm.autogenerated) return
1522

1623
const lines = params.lines
1724
let inLegacyNote = false
18-
let noteStartLine = null
19-
let noteContent = []
25+
let noteStartLine: number | null = null
26+
let noteContent: NoteContentItem[] = []
2027

2128
for (let i = 0; i < lines.length; i++) {
2229
const line = lines[i]
@@ -144,7 +151,11 @@ export const noteWarningFormatting = {
144151
/**
145152
* Validate content inside legacy {% note %} blocks
146153
*/
147-
function validateNoteContent(noteContent, noteStartLine, onError) {
154+
function validateNoteContent(
155+
noteContent: NoteContentItem[],
156+
noteStartLine: number | null,
157+
onError: RuleErrorCallback,
158+
) {
148159
if (noteContent.length === 0) return
149160

150161
const contentLines = noteContent.filter((item) => item.text.trim() !== '')
@@ -195,7 +206,12 @@ function validateNoteContent(noteContent, noteStartLine, onError) {
195206
/**
196207
* Validate content inside new-style callouts
197208
*/
198-
function validateCalloutContent(calloutContent, calloutType, calloutStartLine, onError) {
209+
function validateCalloutContent(
210+
calloutContent: NoteContentItem[],
211+
calloutType: string,
212+
calloutStartLine: number,
213+
onError: RuleErrorCallback,
214+
) {
199215
if (calloutContent.length === 0) return
200216

201217
const contentLines = calloutContent.filter((item) => item.text.trim() !== '>')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'markdownlint-rule-search-replace'

src/content-linter/tests/unit/british-english-quotes.js renamed to src/content-linter/tests/unit/british-english-quotes.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
2323
'The article "[AUTOTITLE]", covers this topic.',
2424
].join('\n')
2525
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
26-
const errors = result.markdown
26+
// Markdownlint error objects include detail property not in base LintError type
27+
const errors = result.markdown as any[]
2728
expect(errors.length).toBe(2)
2829
expect(errors[0].lineNumber).toBe(1)
2930
if (errors[0].detail) {
@@ -43,7 +44,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
4344
'See the guide titled "Getting Started", for details.',
4445
].join('\n')
4546
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
46-
const errors = result.markdown
47+
// Markdownlint error objects include detail property not in base LintError type
48+
const errors = result.markdown as any[]
4749
expect(errors.length).toBe(4)
4850
if (errors[0].detail) {
4951
expect(errors[0].detail).toContain('period inside')
@@ -65,7 +67,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
6567
"The term 'API endpoint', refers to a specific URL.",
6668
].join('\n')
6769
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
68-
const errors = result.markdown
70+
// Markdownlint error objects include detail property not in base LintError type
71+
const errors = result.markdown as any[]
6972
expect(errors.length).toBe(2)
7073
if (errors[0].detail) {
7174
expect(errors[0].detail).toContain('period inside')
@@ -86,7 +89,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
8689
'The command `git commit -m "Fix bug";` creates a commit.',
8790
].join('\n')
8891
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
89-
const errors = result.markdown
92+
// Markdownlint error objects include detail property not in base LintError type
93+
const errors = result.markdown as any[]
9094
expect(errors.length).toBe(0)
9195
})
9296

@@ -97,7 +101,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
97101
'The webhook URL http://api.service.com"endpoint" should work.',
98102
].join('\n')
99103
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
100-
const errors = result.markdown
104+
// Markdownlint error objects include detail property not in base LintError type
105+
const errors = result.markdown as any[]
101106
expect(errors.length).toBe(0)
102107
})
103108

@@ -107,7 +112,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
107112
'The guide "Setup Instructions", explains everything.',
108113
].join('\n')
109114
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
110-
const errors = result.markdown
115+
// Markdownlint error objects include detail and fixInfo properties not in base LintError type
116+
const errors = result.markdown as any[]
111117
expect(errors.length).toBe(2)
112118

113119
// Check that fix info is provided
@@ -124,7 +130,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
124130
'As Fatima noted, "Testing is crucial"; quality depends on it.',
125131
].join('\n')
126132
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
127-
const errors = result.markdown
133+
// Markdownlint error objects include detail property not in base LintError type
134+
const errors = result.markdown as any[]
128135
expect(errors.length).toBe(2)
129136
expect(errors[0].lineNumber).toBe(1)
130137
expect(errors[1].lineNumber).toBe(2)
@@ -136,7 +143,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
136143
'The message "Error: \'Invalid input\'" appears sometimes.',
137144
].join('\n')
138145
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
139-
const errors = result.markdown
146+
// Markdownlint error objects include detail property not in base LintError type
147+
const errors = result.markdown as any[]
140148
expect(errors.length).toBe(1)
141149
if (errors[0].detail) {
142150
expect(errors[0].detail).toContain('period inside')
@@ -150,7 +158,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
150158
'Reference "[AUTOTITLE]" .',
151159
].join('\n')
152160
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
153-
const errors = result.markdown
161+
// Markdownlint error objects include detail property not in base LintError type
162+
const errors = result.markdown as any[]
154163
expect(errors.length).toBe(3)
155164
if (errors[0].detail) {
156165
expect(errors[0].detail).toContain('period inside')
@@ -194,7 +203,8 @@ describe(britishEnglishQuotes.names.join(' - '), () => {
194203
'Dmitri explained, "The workflow has multiple stages."',
195204
].join('\n')
196205
const result = await runRule(britishEnglishQuotes, { strings: { markdown } })
197-
const errors = result.markdown
206+
// Markdownlint error objects include detail property not in base LintError type
207+
const errors = result.markdown as any[]
198208
expect(errors.length).toBe(4)
199209
expect(errors[0].lineNumber).toBe(3) // config.yml line
200210
expect(errors[1].lineNumber).toBe(4) // Docker Basics line

src/content-linter/tests/unit/search-replace.js renamed to src/content-linter/tests/unit/search-replace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ describe(searchReplace.names.join(' - '), () => {
179179

180180
const result = await runRule(searchReplace, {
181181
strings: { markdown },
182-
config: searchReplaceConfig,
182+
ruleConfig: searchReplaceConfig['search-replace'],
183183
markdownlintOptions: { frontMatter: null },
184184
})
185185
const errors = result.markdown

src/content-render/liquid/ifversion.js renamed to src/content-render/liquid/ifversion.ts

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1-
import { Tag, isTruthy, Value, TokenizationError } from 'liquidjs'
1+
import {
2+
Tag,
3+
isTruthy,
4+
Value,
5+
TokenizationError,
6+
type TagToken,
7+
type Context,
8+
type Emitter,
9+
type Template,
10+
type TopLevelToken,
11+
} from 'liquidjs'
212
import versionSatisfiesRange from '@/versions/lib/version-satisfies-range'
3-
import supportedOperators from './ifversion-supported-operators'
13+
import supportedOperators, {
14+
type IfversionSupportedOperator,
15+
} from './ifversion-supported-operators'
16+
17+
interface Branch {
18+
cond: string
19+
templates: Template[]
20+
}
21+
22+
interface VersionObj {
23+
shortName: string
24+
hasNumberedReleases?: boolean
25+
currentRelease?: string
26+
internalLatestRelease?: string
27+
}
428

529
const SyntaxHelp =
630
"Syntax Error in 'ifversion' with range - Valid syntax: ifversion [plan] [operator] [releaseNumber]"
@@ -14,15 +38,20 @@ const notRegex = /(?:^|\s)not\s/
1438
// using semver to evaluate release numbers instead of doing standard number comparisons, which
1539
// don't work the way we want because they evaluate 3.2 > 3.10 = true.
1640
export default class extends Tag {
41+
tagToken: TagToken
42+
branches: Branch[]
43+
elseTemplates: Template[]
44+
currentVersionObj: VersionObj | null = null
45+
1746
// The following is verbatim from https://github.com/harttle/liquidjs/blob/v9.22.1/src/builtin/tags/if.ts
18-
constructor(tagToken, remainTokens, liquid) {
47+
constructor(tagToken: TagToken, remainTokens: TopLevelToken[], liquid: any) {
1948
super(tagToken, remainTokens, liquid)
2049

2150
this.tagToken = tagToken
2251
this.branches = []
2352
this.elseTemplates = []
2453

25-
let p
54+
let p: Template[]
2655
const stream = this.liquid.parser
2756
.parseStream(remainTokens)
2857
.on('start', () =>
@@ -31,15 +60,15 @@ export default class extends Tag {
3160
templates: (p = []),
3261
}),
3362
)
34-
.on('tag:elsif', (token) => {
63+
.on('tag:elsif', (token: any) => {
3564
this.branches.push({
3665
cond: token.args,
3766
templates: (p = []),
3867
})
3968
})
4069
.on('tag:else', () => (p = this.elseTemplates))
4170
.on('tag:endif', () => stream.stop())
42-
.on('template', (tpl) => p.push(tpl))
71+
.on('template', (tpl: Template) => p.push(tpl))
4372
.on('end', () => {
4473
throw new Error(`tag ${tagToken.getText()} not closed`)
4574
})
@@ -49,10 +78,10 @@ export default class extends Tag {
4978

5079
// The following is _mostly_ verbatim from https://github.com/harttle/liquidjs/blob/v9.22.1/src/builtin/tags/if.ts
5180
// The additions here are the handleNots(), handleOperators(), and handleVersionNames() calls.
52-
*render(ctx, emitter) {
81+
*render(ctx: Context, emitter: Emitter): Generator<any, void, unknown> {
5382
const r = this.liquid.renderer
5483

55-
this.currentVersionObj = ctx.environments.currentVersionObj
84+
this.currentVersionObj = (ctx.environments as any).currentVersionObj
5685

5786
for (const branch of this.branches) {
5887
let resolvedBranchCond = branch.cond
@@ -67,8 +96,8 @@ export default class extends Tag {
6796
// Resolve version names to boolean values for Markdown API context.
6897
// This will replace syntax like `fpt or ghec` with `true or false` based on current version.
6998
// Only apply this transformation in Markdown API context to avoid breaking existing functionality.
70-
if (ctx.environments.markdownRequested) {
71-
resolvedBranchCond = this.handleVersionNames(resolvedBranchCond, ctx)
99+
if ((ctx.environments as any).markdownRequested) {
100+
resolvedBranchCond = this.handleVersionNames(resolvedBranchCond)
72101
}
73102

74103
// Use Liquid's native function for the final evaluation.
@@ -82,13 +111,13 @@ export default class extends Tag {
82111
yield r.renderTemplates(this.elseTemplates, ctx, emitter)
83112
}
84113

85-
handleNots(resolvedBranchCond) {
114+
handleNots(resolvedBranchCond: string): string {
86115
if (!notRegex.test(resolvedBranchCond)) return resolvedBranchCond
87116

88117
const condArray = resolvedBranchCond.split(' ')
89118

90119
// Find the first index in the array that contains "not".
91-
const notIndex = condArray.findIndex((el) => el === 'not')
120+
const notIndex = condArray.findIndex((el: string) => el === 'not')
92121

93122
// E.g., ['not', 'fpt']
94123
const condParts = condArray.slice(notIndex, notIndex + 2)
@@ -99,10 +128,10 @@ export default class extends Tag {
99128
// If the current version is the version being evaluated in the conditional,
100129
// that is negated and resolved to false. If it's NOT the version being
101130
// evaluated, that resolves to true.
102-
const resolvedBoolean = !(versionToEvaluate === this.currentVersionObj.shortName)
131+
const resolvedBoolean = !(versionToEvaluate === this.currentVersionObj!.shortName)
103132

104133
// Replace syntax like `not fpt` with `true` or `false`.
105-
resolvedBranchCond = resolvedBranchCond.replace(condParts.join(' '), resolvedBoolean)
134+
resolvedBranchCond = resolvedBranchCond.replace(condParts.join(' '), String(resolvedBoolean))
106135

107136
// Run this function recursively until we've resolved all the nots.
108137
if (notRegex.test(resolvedBranchCond)) {
@@ -112,14 +141,16 @@ export default class extends Tag {
112141
return resolvedBranchCond
113142
}
114143

115-
handleOperators(resolvedBranchCond) {
144+
handleOperators(resolvedBranchCond: string): string {
116145
if (!supportedOperatorsRegex.test(resolvedBranchCond)) return resolvedBranchCond
117146

118147
// If this conditional contains multiple parts using `or` or `and`, get only the conditional with operators.
119148
const condArray = resolvedBranchCond.split(' ')
120149

121150
// Find the first index in the array that contains an operator.
122-
const operatorIndex = condArray.findIndex((el) => supportedOperators.find((op) => el === op))
151+
const operatorIndex = condArray.findIndex((el: string) =>
152+
supportedOperators.find((op: string) => el === op),
153+
)
123154

124155
// E.g., ['ghes', '<', '3.1']
125156
const condParts = condArray.slice(operatorIndex - 1, operatorIndex + 2)
@@ -129,7 +160,8 @@ export default class extends Tag {
129160

130161
// Make sure the operator is supported and the release number matches `\d\d?\.\d\d?`
131162
const syntaxError =
132-
!supportedOperators.includes(operator) || !releaseRegex.test(releaseToEvaluate)
163+
!supportedOperators.includes(operator as IfversionSupportedOperator) ||
164+
!releaseRegex.test(releaseToEvaluate)
133165

134166
if (syntaxError) {
135167
throw new TokenizationError(SyntaxHelp, this.tagToken)
@@ -154,25 +186,25 @@ export default class extends Tag {
154186
? this.currentVersionObj.currentRelease
155187
: this.currentVersionObj.internalLatestRelease
156188

157-
let resolvedBoolean
189+
let resolvedBoolean: boolean
158190
if (operator === '!=') {
159191
// If this is the current plan, compare the release numbers. (Our semver package doesn't handle !=.)
160192
// If it's not the current version, it's always true.
161193
resolvedBoolean =
162-
versionShortName === this.currentVersionObj.shortName
194+
versionShortName === this.currentVersionObj!.shortName
163195
? releaseToEvaluate !== currentRelease
164196
: true
165197
} else {
166198
// If this is the current plan, evaluate the operator using semver.
167199
// If it's not the current plan, it's always false.
168200
resolvedBoolean =
169-
versionShortName === this.currentVersionObj.shortName
170-
? versionSatisfiesRange(currentRelease, `${operator}${releaseToEvaluate}`)
201+
versionShortName === this.currentVersionObj!.shortName
202+
? versionSatisfiesRange(currentRelease!, `${operator}${releaseToEvaluate}`)
171203
: false
172204
}
173205

174206
// Replace syntax like `fpt or ghes < 3.0` with `fpt or true` or `fpt or false`.
175-
resolvedBranchCond = resolvedBranchCond.replace(condParts.join(' '), resolvedBoolean)
207+
resolvedBranchCond = resolvedBranchCond.replace(condParts.join(' '), String(resolvedBoolean))
176208

177209
// Run this function recursively until we've resolved all the special operators.
178210
if (supportedOperatorsRegex.test(resolvedBranchCond)) {
@@ -182,21 +214,21 @@ export default class extends Tag {
182214
return resolvedBranchCond
183215
}
184216

185-
handleVersionNames(resolvedBranchCond, ctx) {
217+
handleVersionNames(resolvedBranchCond: string): string {
186218
if (!this.currentVersionObj) {
187219
console.warn('currentVersionObj not found in ifversion context.')
188220
return resolvedBranchCond
189221
}
190222

191223
// Split the condition into tokens for processing
192224
const tokens = resolvedBranchCond.split(/\s+/)
193-
const processedTokens = tokens.map((token) => {
225+
const processedTokens = tokens.map((token: string) => {
194226
// Check if the token is a version short name (fpt, ghec, ghes, ghae)
195227
const versionShortNames = ['fpt', 'ghec', 'ghes', 'ghae']
196228
if (versionShortNames.includes(token)) {
197229
// Transform version names to boolean values for Markdown API
198230
// This fixes the original issue where version names were undefined in API context
199-
return token === this.currentVersionObj.shortName ? 'true' : 'false'
231+
return token === this.currentVersionObj!.shortName ? 'true' : 'false'
200232
}
201233
// Return the token unchanged if it's not a version name
202234
return token

src/content-render/tests/table-accessibility-labels.js renamed to src/content-render/tests/table-accessibility-labels.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { EOL } from 'os'
66

77
// Use platform-specific line endings for realistic tests when templates have
88
// been loaded from disk
9-
const nl = (str) => str.replace(/\n/g, EOL)
9+
const nl = (str: string) => str.replace(/\n/g, EOL)
1010

1111
describe('table accessibility labels', () => {
1212
test('adds aria-labelledby to tables following headings', async () => {

0 commit comments

Comments
 (0)