Skip to content

Commit df70f19

Browse files
authored
Convert JavaScript files to TypeScript in multiple directories (#55550)
1 parent 269910c commit df70f19

File tree

7 files changed

+91
-40
lines changed

7 files changed

+91
-40
lines changed

src/article-api/tests/pageinfo.js renamed to src/article-api/tests/pageinfo.ts

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@ import { get } from '#src/tests/helpers/e2etest.js'
44
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
55
import { latest } from '#src/versions/lib/enterprise-server-releases.js'
66

7-
const makeURL = (pathname) => `/api/article/meta?${new URLSearchParams({ pathname })}`
7+
const makeURL = (pathname: string): string =>
8+
`/api/article/meta?${new URLSearchParams({ pathname })}`
9+
10+
interface PageMetadata {
11+
product: string
12+
title: string
13+
intro: string
14+
}
15+
16+
interface ErrorResponse {
17+
error: string
18+
}
819

920
describe('pageinfo api', () => {
1021
beforeAll(() => {
@@ -27,7 +38,7 @@ describe('pageinfo api', () => {
2738
test('happy path', async () => {
2839
const res = await get(makeURL('/en/get-started/start-your-journey'))
2940
expect(res.statusCode).toBe(200)
30-
const meta = JSON.parse(res.body)
41+
const meta = JSON.parse(res.body) as PageMetadata
3142
expect(meta.product).toBe('Get started')
3243
expect(meta.title).toBe('Start your journey')
3344
expect(meta.intro).toBe(
@@ -45,28 +56,28 @@ describe('pageinfo api', () => {
4556
test('a pathname that does not exist', async () => {
4657
const res = await get(makeURL('/en/never/heard/of'))
4758
expect(res.statusCode).toBe(404)
48-
const { error } = JSON.parse(res.body)
59+
const { error } = JSON.parse(res.body) as ErrorResponse
4960
expect(error).toBe("No page found for '/en/never/heard/of'")
5061
})
5162

5263
test("no 'pathname' query string at all", async () => {
5364
const res = await get('/api/article/meta')
5465
expect(res.statusCode).toBe(400)
55-
const { error } = JSON.parse(res.body)
66+
const { error } = JSON.parse(res.body) as ErrorResponse
5667
expect(error).toBe("No 'pathname' query")
5768
})
5869

5970
test("empty 'pathname' query string", async () => {
6071
const res = await get('/api/article/meta?pathname=%20')
6172
expect(res.statusCode).toBe(400)
62-
const { error } = JSON.parse(res.body)
73+
const { error } = JSON.parse(res.body) as ErrorResponse
6374
expect(error).toBe("'pathname' query empty")
6475
})
6576

6677
test('repeated pathname query string key', async () => {
6778
const res = await get('/api/article/meta?pathname=a&pathname=b')
6879
expect(res.statusCode).toBe(400)
69-
const { error } = JSON.parse(res.body)
80+
const { error } = JSON.parse(res.body) as ErrorResponse
7081
expect(error).toBe("Multiple 'pathname' keys")
7182
})
7283

@@ -75,28 +86,28 @@ describe('pageinfo api', () => {
7586
{
7687
const res = await get(makeURL('/en/olden-days'))
7788
expect(res.statusCode).toBe(200)
78-
const meta = JSON.parse(res.body)
89+
const meta = JSON.parse(res.body) as PageMetadata
7990
expect(meta.title).toBe('HubGit.com Fixture Documentation')
8091
}
8192
// Trailing slashes are always removed
8293
{
8394
const res = await get(makeURL('/en/olden-days/'))
8495
expect(res.statusCode).toBe(200)
85-
const meta = JSON.parse(res.body)
96+
const meta = JSON.parse(res.body) as PageMetadata
8697
expect(meta.title).toBe('HubGit.com Fixture Documentation')
8798
}
8899
// Short code for latest version
89100
{
90101
const res = await get(makeURL('/en/enterprise-server@latest/get-started/liquid/ifversion'))
91102
expect(res.statusCode).toBe(200)
92-
const meta = JSON.parse(res.body)
103+
const meta = JSON.parse(res.body) as PageMetadata
93104
expect(meta.intro).toMatch(/\(not on fpt\)/)
94105
}
95106
// A URL that doesn't have fpt as an available version
96107
{
97108
const res = await get(makeURL('/en/get-started/versioning/only-ghec-and-ghes'))
98109
expect(res.statusCode).toBe(200)
99-
const meta = JSON.parse(res.body)
110+
const meta = JSON.parse(res.body) as PageMetadata
100111
expect(meta.title).toBe('Only in Enterprise Cloud and Enterprise Server')
101112
}
102113
})
@@ -108,14 +119,14 @@ describe('pageinfo api', () => {
108119
{
109120
const res = await get(makeURL('/en/get-started/liquid/ifversion'))
110121
expect(res.statusCode).toBe(200)
111-
const meta = JSON.parse(res.body)
122+
const meta = JSON.parse(res.body) as PageMetadata
112123
expect(meta.intro).toMatch(/\(on fpt\)/)
113124
}
114125
// Second on any other version
115126
{
116127
const res = await get(makeURL('/en/enterprise-server@latest/get-started/liquid/ifversion'))
117128
expect(res.statusCode).toBe(200)
118-
const meta = JSON.parse(res.body)
129+
const meta = JSON.parse(res.body) as PageMetadata
119130
expect(meta.intro).toMatch(/\(not on fpt\)/)
120131
}
121132
})
@@ -125,7 +136,7 @@ describe('pageinfo api', () => {
125136
{
126137
const res = await get(makeURL('/en'))
127138
expect(res.statusCode).toBe(200)
128-
const meta = JSON.parse(res.body)
139+
const meta = JSON.parse(res.body) as PageMetadata
129140
expect(meta.title).toMatch('HubGit.com Fixture Documentation')
130141
}
131142
// enterprise-server with language specified
@@ -137,7 +148,7 @@ describe('pageinfo api', () => {
137148
{
138149
const res = await get(makeURL(`/en/enterprise-server@${latest}`))
139150
expect(res.statusCode).toBe(200)
140-
const meta = JSON.parse(res.body)
151+
const meta = JSON.parse(res.body) as PageMetadata
141152
expect(meta.title).toMatch('HubGit Enterprise Server Fixture Documentation')
142153
}
143154
})
@@ -147,14 +158,14 @@ describe('pageinfo api', () => {
147158
{
148159
const res = await get(makeURL('/'))
149160
expect(res.statusCode).toBe(200)
150-
const meta = JSON.parse(res.body)
161+
const meta = JSON.parse(res.body) as PageMetadata
151162
expect(meta.title).toMatch('HubGit.com Fixture Documentation')
152163
}
153164
// enterprise-server without language specified
154165
{
155166
const res = await get(makeURL('/enterprise-server@latest'))
156167
expect(res.statusCode).toBe(200)
157-
const meta = JSON.parse(res.body)
168+
const meta = JSON.parse(res.body) as PageMetadata
158169
expect(meta.title).toMatch('HubGit Enterprise Server Fixture Documentation')
159170
}
160171
})
@@ -169,38 +180,38 @@ describe('pageinfo api', () => {
169180
{
170181
const res = await get(makeURL('/en/enterprise-server@3.2'))
171182
expect(res.statusCode).toBe(200)
172-
const meta = JSON.parse(res.body)
183+
const meta = JSON.parse(res.body) as PageMetadata
173184
expect(meta.title).toMatch('GitHub Enterprise Server 3.2 Help Documentation')
174185
}
175186

176187
// The oldest known archived version that we proxy
177188
{
178189
const res = await get(makeURL('/en/enterprise/11.10.340'))
179190
expect(res.statusCode).toBe(200)
180-
const meta = JSON.parse(res.body)
191+
const meta = JSON.parse(res.body) as PageMetadata
181192
expect(meta.title).toMatch('GitHub Enterprise Server 11.10.340 Help Documentation')
182193
}
183194
})
184195

185196
test('pathname has to start with /', async () => {
186197
const res = await get(makeURL('ip'))
187198
expect(res.statusCode).toBe(400)
188-
const { error } = JSON.parse(res.body)
199+
const { error } = JSON.parse(res.body) as ErrorResponse
189200
expect(error).toBe("'pathname' has to start with /")
190201
})
191202

192203
test("pathname can't contain spaces /", async () => {
193204
const res = await get(makeURL('/en foo bar'))
194205
expect(res.statusCode).toBe(400)
195-
const { error } = JSON.parse(res.body)
206+
const { error } = JSON.parse(res.body) as ErrorResponse
196207
expect(error).toBe("'pathname' cannot contain whitespace")
197208
})
198209

199210
describe('translations', () => {
200211
test('Japanese page', async () => {
201212
const res = await get(makeURL('/ja/get-started/start-your-journey/hello-world'))
202213
expect(res.statusCode).toBe(200)
203-
const meta = JSON.parse(res.body)
214+
const meta = JSON.parse(res.body) as PageMetadata
204215
expect(meta.product).toBe('はじめに')
205216
expect(meta.title).toBe('こんにちは World')
206217
expect(meta.intro).toBe('この Hello World 演習に従って、HubGit の使用を開始します。')
@@ -213,8 +224,8 @@ describe('pageinfo api', () => {
213224
// even exist on disk. So it'll fall back to English.
214225
const translationRes = await get(makeURL('/ja/get-started/start-your-journey'))
215226
expect(translationRes.statusCode).toBe(200)
216-
const en = JSON.parse(enRes.body)
217-
const translation = JSON.parse(translationRes.body)
227+
const en = JSON.parse(enRes.body) as PageMetadata
228+
const translation = JSON.parse(translationRes.body) as PageMetadata
218229
expect(en.title).toBe(translation.title)
219230
expect(en.intro).toBe(translation.intro)
220231
})

src/assets/lib/image-density.js renamed to src/assets/lib/image-density.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import fs from 'fs'
22

3+
interface ImageDensityMap {
4+
[path: string]: string
5+
}
6+
37
const file = fs.readFileSync('./src/assets/lib/image-density.txt', 'utf8')
48

5-
export const IMAGE_DENSITY = Object.fromEntries(
9+
export const IMAGE_DENSITY: ImageDensityMap = Object.fromEntries(
610
file.split('\n').map((line) => {
711
const [path, density] = line.split(' ')
812
return [path, density]

src/color-schemes/tests/use-theme.js renamed to src/color-schemes/tests/use-theme.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@ import {
55
getCssTheme,
66
defaultCSSTheme,
77
defaultComponentTheme,
8-
} from '../components/useTheme.ts'
8+
} from '../components/useTheme'
9+
10+
interface ThemeCookieValue {
11+
color_mode?: string
12+
light_theme?: {
13+
name: string
14+
color_mode: string
15+
}
16+
dark_theme?: {
17+
name: string
18+
color_mode: string
19+
}
20+
}
921

1022
describe('getTheme basics', () => {
1123
test('always return an object with certain keys', () => {
12-
const cookieValue = JSON.stringify({})
24+
const cookieValue = JSON.stringify({} as ThemeCookieValue)
1325
expect(getCssTheme(cookieValue)).toEqual(defaultCSSTheme)
1426
expect(getComponentTheme(cookieValue)).toEqual(defaultComponentTheme)
1527
})
@@ -25,7 +37,7 @@ describe('getTheme basics', () => {
2537
color_mode: 'dark',
2638
light_theme: { name: 'light_colorblind', color_mode: 'light' },
2739
dark_theme: { name: 'dark_tritanopia', color_mode: 'dark' },
28-
})
40+
} as ThemeCookieValue)
2941

3042
const cssTheme = getCssTheme(cookieValue)
3143
expect(cssTheme.colorMode).toBe('dark')

src/content-render/unified/rewrite-asset-img-tags.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { visit, SKIP } from 'unist-util-visit'
2-
import { IMAGE_DENSITY } from '../../assets/lib/image-density.js'
2+
import { IMAGE_DENSITY } from '../../assets/lib/image-density.ts'
33

44
// This number must match a width we're willing to accept in a dynamic
55
// asset URL.

src/events/lib/get-document-type.js renamed to src/events/lib/get-document-type.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
// This function derives the document type from the *relative path* segment length,
2-
// where a relative path refers to the content path starting with the product dir.
3-
// For example: actions/index.md or github/getting-started-with-github/quickstart.md.
4-
export default function getDocumentType(relativePath) {
1+
/**
2+
* Document types used by the system
3+
*/
4+
type DocumentType = 'homepage' | 'product' | 'category' | 'mapTopic' | 'article' | 'early-access'
5+
6+
/**
7+
* This function derives the document type from the *relative path* segment length,
8+
* where a relative path refers to the content path starting with the product dir.
9+
* For example: actions/index.md or github/getting-started-with-github/quickstart.md.
10+
*/
11+
export default function getDocumentType(relativePath: string): DocumentType {
512
// A non-index file is ALWAYS considered an article in this approach,
613
// even if it's at the category level (like actions/quickstart.md)
714
if (!relativePath.endsWith('index.md')) {
@@ -13,9 +20,15 @@ export default function getDocumentType(relativePath) {
1320
// Early Access has an extra tree segment, so it has a different number of segments.
1421
const isEarlyAccess = relativePath.startsWith('early-access')
1522

16-
const publicDocs = ['homepage', 'product', 'category', 'mapTopic']
23+
const publicDocs: DocumentType[] = ['homepage', 'product', 'category', 'mapTopic']
1724

18-
const earlyAccessDocs = ['homepage', 'early-access', 'product', 'category', 'mapTopic']
25+
const earlyAccessDocs: DocumentType[] = [
26+
'homepage',
27+
'early-access',
28+
'product',
29+
'category',
30+
'mapTopic',
31+
]
1932

2033
// Anything beyond the largest depth is assumed to be a mapTopic
2134
return isEarlyAccess

src/frame/lib/page.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { productMap } from '#src/products/lib/all-products.js'
1313
import slash from 'slash'
1414
import readFileContents from './read-file-contents.js'
1515
import getLinkData from '#src/learning-track/lib/get-link-data.js'
16-
import getDocumentType from '#src/events/lib/get-document-type.js'
16+
import getDocumentType from '#src/events/lib/get-document-type.ts'
1717
import { allTools } from '#src/tools/lib/all-tools.js'
1818
import { renderContentWithFallback } from '#src/languages/lib/render-with-fallback.js'
1919
import { deprecated, supported } from '#src/versions/lib/enterprise-server-releases.js'

src/release-notes/tests/yaml.js renamed to src/release-notes/tests/yaml.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import yaml from 'js-yaml'
77

88
import { liquid } from '#src/content-render/index.js'
99

10+
interface ReleaseNoteContent {
11+
intro: string
12+
sections: {
13+
[key: string]: Array<string | { [prop: string]: string }>
14+
}
15+
currentWeek?: boolean
16+
}
17+
1018
const ghesReleaseNoteRootPath = 'data/release-notes'
1119
const yamlWalkOptions = {
1220
globs: ['**/*.yml'],
@@ -18,17 +26,17 @@ const yamlFileList = walk(ghesReleaseNoteRootPath, yamlWalkOptions).sort()
1826
describe('lint enterprise release notes', () => {
1927
if (yamlFileList.length < 1) return
2028
describe.each(yamlFileList)('%s', (yamlAbsPath) => {
21-
let yamlContent
29+
let yamlContent: ReleaseNoteContent
2230
const relativePath = path.relative('', yamlAbsPath)
2331

2432
beforeAll(async () => {
2533
const fileContents = await readFile(yamlAbsPath, 'utf8')
26-
yamlContent = yaml.load(fileContents)
34+
yamlContent = yaml.load(fileContents) as ReleaseNoteContent
2735
})
2836

2937
test('contains valid liquid', () => {
3038
const { intro, sections } = yamlContent
31-
let toLint = { intro }
39+
let toLint: Record<string, string> = { intro }
3240
for (const key in sections) {
3341
const section = sections[key]
3442
const label = `sections.${key}`
@@ -37,7 +45,10 @@ describe('lint enterprise release notes', () => {
3745
toLint = { ...toLint, ...{ [label]: section.join('\n') } }
3846
} else {
3947
for (const prop in section) {
40-
toLint = { ...toLint, ...{ [`${label}.${prop}`]: section[prop] } }
48+
const value = section[prop]
49+
if (typeof value === 'string') {
50+
toLint = { ...toLint, ...{ [`${label}.${prop}`]: value } }
51+
}
4152
}
4253
}
4354
})
@@ -49,7 +60,7 @@ describe('lint enterprise release notes', () => {
4960
}
5061
})
5162

52-
const currentWeeksFound = []
63+
const currentWeeksFound: string[] = []
5364
test('does not have more than one yaml file with currentWeek set to true', () => {
5465
if (!yamlAbsPath.includes('data/release-notes/github-ae')) return
5566
if (yamlContent.currentWeek) currentWeeksFound.push(relativePath)

0 commit comments

Comments
 (0)