1
0
mirror of synced 2025-12-19 18:10:59 -05:00

Convert 28 JavaScript files to TypeScript (#57753)

This commit is contained in:
Kevin Heis
2025-10-06 09:07:33 -07:00
committed by GitHub
parent 140a3f7768
commit 822bdfff67
30 changed files with 126 additions and 88 deletions

View File

@@ -6,11 +6,13 @@
*/
export function printAnnotationResults(
results,
// Using 'any' type as results structure is dynamic and comes from various linting tools with different formats
results: any,
{ skippableRules = [], skippableFlawProperties = [] } = {},
) {
for (const [file, flaws] of Object.entries(results)) {
for (const flaw of flaws) {
// Using 'any' type for flaws as they have varying structures depending on the linting rule
for (const flaw of flaws as any) {
if (intersection(flaw.ruleNames, skippableRules)) {
continue
}
@@ -52,6 +54,7 @@ export function printAnnotationResults(
}
}
function intersection(arr1, arr2) {
return arr1.some((item) => arr2.includes(item))
// Using 'any' types for generic array intersection utility function
function intersection(arr1: any[], arr2: any[]) {
return arr1.some((item: any) => arr2.includes(item))
}

View File

@@ -1,3 +1,4 @@
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { addError } from 'markdownlint-rule-helpers'
import { intersection } from 'lodash-es'
@@ -5,12 +6,13 @@ import { getFrontmatter } from '../helpers/utils'
import { formatAjvErrors } from '../helpers/schema-utils'
import { frontmatter, deprecatedProperties } from '@/frame/lib/frontmatter'
import readFrontmatter from '@/frame/lib/read-frontmatter'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
export const frontmatterSchema = {
export const frontmatterSchema: Rule = {
names: ['GHD012', 'frontmatter-schema'],
description: 'Frontmatter must conform to the schema',
tags: ['frontmatter', 'schema'],
function: (params, onError) => {
function: (params: RuleParams, onError: RuleErrorCallback) => {
const fm = getFrontmatter(params.lines)
if (!fm) return
@@ -22,25 +24,25 @@ export const frontmatterSchema = {
for (const key of deprecatedKeys) {
// Early access articles are allowed to have deprecated properties
if (params.name.includes('early-access')) continue
const line = params.lines.find((line) => line.trim().startsWith(key))
const lineNumber = params.lines.indexOf(line) + 1
const line = params.lines.find((line: string) => line.trim().startsWith(key))
const lineNumber = params.lines.indexOf(line!) + 1
addError(
onError,
lineNumber,
`The frontmatter property '${key}' is deprecated. Please remove the property from your article's frontmatter.`,
line,
[1, line.length],
line!,
[1, line!.length],
null, // No fix possible
)
}
// Check that the frontmatter matches the schema
const { errors } = readFrontmatter(params.lines.join('\n'), { schema: frontmatter.schema })
const formattedErrors = formatAjvErrors(errors)
const formattedErrors = formatAjvErrors(errors as any)
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.
const query = (line) => line.trim().startsWith(`${error.searchProperty}:`)
const query = (line: string) => line.trim().startsWith(`${error.searchProperty}:`)
const line = error.searchProperty === '' ? null : params.lines.find(query)
const lineNumber = line ? params.lines.indexOf(line) + 1 : 1
addError(

View File

@@ -1,6 +1,8 @@
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { addError } from 'markdownlint-rule-helpers'
import { forEachInlineChild, getRange } from '../helpers/utils'
import type { RuleParams, RuleErrorCallback, MarkdownToken, Rule } from '../../types'
const excludeStartWords = ['image', 'graphic']
@@ -8,21 +10,21 @@ const excludeStartWords = ['image', 'graphic']
Images should have meaningful alternative text (alt text)
and should not begin with words like "image" or "graphic".
*/
export const imageAltTextExcludeStartWords = {
export const imageAltTextExcludeStartWords: Rule = {
names: ['GHD031', 'image-alt-text-exclude-words'],
description: 'Alternate text for images should not begin with words like "image" or "graphic"',
tags: ['accessibility', 'images'],
parser: 'markdownit',
function: (params, onError) => {
forEachInlineChild(params, 'image', function forToken(token) {
const imageAltText = token.content.trim()
function: (params: RuleParams, onError: RuleErrorCallback) => {
forEachInlineChild(params, 'image', function forToken(token: MarkdownToken) {
// If the alt text is empty, there is nothing to check and you can't
// produce a valid range.
// We can safely return early because the image-alt-text-length rule
// will fail this one.
if (!token.content) return
const imageAltText = token.content.trim()
const range = getRange(token.line, imageAltText)
if (
excludeStartWords.some((excludeWord) => imageAltText.toLowerCase().startsWith(excludeWord))

View File

@@ -1,15 +1,18 @@
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { filterTokens } from 'markdownlint-rule-helpers'
import { addFixErrorDetail, getRange } from '../helpers/utils'
import { allLanguageKeys } from '@/languages/lib/languages'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
export const internalLinksNoLang = {
export const internalLinksNoLang: Rule = {
names: ['GHD002', 'internal-links-no-lang'],
description: 'Internal links must not have a hardcoded language code',
tags: ['links', 'url'],
parser: 'markdownit',
function: (params, onError) => {
filterTokens(params, 'inline', (token) => {
function: (params: RuleParams, onError: RuleErrorCallback) => {
// Using 'any' type for token as markdownlint-rule-helpers doesn't provide TypeScript types
filterTokens(params, 'inline', (token: any) => {
for (const child of token.children) {
if (child.type !== 'link_open') continue
@@ -18,14 +21,17 @@ export const internalLinksNoLang = {
// ['href', 'get-started'], ['target', '_blank'],
// ['rel', 'canonical'],
// ]
// Attribute arrays are tuples of [attributeName, attributeValue] from markdownit parser
const hrefsMissingSlashes = child.attrs
// The attribute could also be `target` or `rel`
.filter((attr) => attr[0] === 'href')
.filter((attr) => attr[1].startsWith('/') || !attr[1].startsWith('//'))
.filter((attr: [string, string]) => attr[0] === 'href')
.filter((attr: [string, string]) => attr[1].startsWith('/') || !attr[1].startsWith('//'))
// Filter out link paths that start with language code
.filter((attr) => allLanguageKeys.some((lang) => attr[1].split('/')[1] === lang))
.filter((attr: [string, string]) =>
allLanguageKeys.some((lang) => attr[1].split('/')[1] === lang),
)
// Get the link path from the attribute
.map((attr) => attr[1])
.map((attr: [string, string]) => attr[1])
// Create errors for each link path that includes a language code
for (const linkPath of hrefsMissingSlashes) {
const range = getRange(child.line, linkPath)

View File

@@ -1,14 +1,17 @@
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { filterTokens } from 'markdownlint-rule-helpers'
import { addFixErrorDetail, getRange } from '../helpers/utils'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
export const internalLinksSlash = {
export const internalLinksSlash: Rule = {
names: ['GHD003', 'internal-links-slash'],
description: 'Internal links must start with a /',
tags: ['links', 'url'],
parser: 'markdownit',
function: (params, onError) => {
filterTokens(params, 'inline', (token) => {
function: (params: RuleParams, onError: RuleErrorCallback) => {
// Using 'any' type for token as markdownlint-rule-helpers doesn't provide TypeScript types
filterTokens(params, 'inline', (token: any) => {
for (const child of token.children) {
if (child.type !== 'link_open') continue
@@ -17,20 +20,21 @@ export const internalLinksSlash = {
// ['href', '/get-started'], ['target', '_blank'],
// ['rel', 'canonical'],
// ]
// Attribute arrays are tuples of [attributeName, attributeValue] from markdownit parser
const hrefsMissingSlashes = child.attrs
// The attribute could also be `target` or `rel`
.filter((attr) => attr[0] === 'href')
.filter((attr: [string, string]) => attr[0] === 'href')
// Filter out prefixes we don't want to check
.filter(
(attr) =>
(attr: [string, string]) =>
!['http', 'mailto', '#', '/'].some((ignorePrefix) =>
attr[1].startsWith(ignorePrefix),
),
)
// We can ignore empty links because MD042 from markdownlint catches empty links
.filter((attr) => attr[1] !== '')
.filter((attr: [string, string]) => attr[1] !== '')
// Get the link path from the attribute
.map((attr) => attr[1])
.map((attr: [string, string]) => attr[1])
// Create errors for each link path that doesn't start with a /
for (const linkPath of hrefsMissingSlashes) {

View File

@@ -1,15 +1,16 @@
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { addError, filterTokens } from 'markdownlint-rule-helpers'
import type { RuleParams, RuleErrorCallback } from '../../types'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
import { doesStringEndWithPeriod, getRange, isStringQuoted } from '../helpers/utils'
export const linkPunctuation = {
export const linkPunctuation: Rule = {
names: ['GHD001', 'link-punctuation'],
description: 'Internal link titles must not contain punctuation',
tags: ['links', 'url'],
parser: 'markdownit',
function: (params: RuleParams, onError: RuleErrorCallback) => {
// Using 'any' type for token as markdownlint-rule-helpers doesn't provide TypeScript types
filterTokens(params, 'inline', (token: any) => {
const { children, line } = token
let inLink = false

View File

@@ -1,8 +1,10 @@
import { TokenKind } from 'liquidjs'
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
import { addError } from 'markdownlint-rule-helpers'
import { getLiquidTokens, conditionalTags, getPositionData } from '../helpers/liquid-utils'
import { isStringQuoted } from '../helpers/utils'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
/*
Checks for instances where a Liquid conditional tag's argument is
@@ -12,18 +14,20 @@ import { isStringQuoted } from '../helpers/utils'
{% if "foo" %}
{% ifversion "bar" %}
*/
export const liquidQuotedConditionalArg = {
export const liquidQuotedConditionalArg: Rule = {
names: ['GHD016', 'liquid-quoted-conditional-arg'],
description: 'Liquid conditional tags should not quote the conditional argument',
tags: ['liquid', 'format'],
function: (params, onError) => {
function: (params: RuleParams, onError: RuleErrorCallback) => {
const content = params.lines.join('\n')
// Using 'any' type for tokens as getLiquidTokens returns tokens from liquid-utils.js which lacks type definitions
const tokens = getLiquidTokens(content)
.filter((token) => token.kind === TokenKind.Tag)
.filter((token) => conditionalTags.includes(token.name))
.filter((token) => {
.filter((token: any) => token.kind === TokenKind.Tag)
.filter((token: any) => conditionalTags.includes(token.name))
.filter((token: any) => {
const tokensArray = token.args.split(/\s+/g)
if (tokensArray.some((arg) => isStringQuoted(arg))) return true
// Using 'any' for args as they come from the untyped liquid token structure
if (tokensArray.some((arg: any) => isStringQuoted(arg))) return true
return false
})

View File

@@ -1,6 +1,7 @@
import { TokenKind } from 'liquidjs'
import { getLiquidTokens, getPositionData } from '../helpers/liquid-utils'
import { addFixErrorDetail } from '../helpers/utils'
import type { RuleParams, RuleErrorCallback, Rule } from '../../types'
/*
Octicons should always have an aria-label attribute even if aria hidden. For example:
@@ -9,20 +10,21 @@ Octicons should always have an aria-label attribute even if aria hidden. For exa
{% octicon "alert" aria-label="alert" aria-hidden="true" %}
{% octicon "alert" aria-label="alert" aria-hidden="true" class="foo" %}
This is necessary for copilot to be able to recognize the svgs correctly when using our API.
This is necessary for copilot to be able to recognize the svgs correctly when using our API.
*/
export const octiconAriaLabels = {
export const octiconAriaLabels: Rule = {
names: ['GHD044', 'octicon-aria-labels'],
description: 'Octicons should always have an aria-label attribute even if aria-hidden.',
tags: ['accessibility', 'octicons'],
parser: 'markdownit',
function: (params, onError) => {
function: (params: RuleParams, onError: RuleErrorCallback) => {
const content = params.lines.join('\n')
// Using 'any' type for tokens as getLiquidTokens returns tokens from liquid-utils.js which lacks type definitions
const tokens = getLiquidTokens(content)
.filter((token) => token.kind === TokenKind.Tag)
.filter((token) => token.name === 'octicon')
.filter((token: any) => token.kind === TokenKind.Tag)
.filter((token: any) => token.name === 'octicon')
for (const token of tokens) {
const { lineNumber, column, length } = getPositionData(token, params.lines)

View File

@@ -41,7 +41,7 @@ describe(frontmatterEarlyAccessReferences.names.join(' - '), () => {
expect(lineNumbers.includes(4)).toBe(false)
expect(lineNumbers.includes(5)).toBe(false)
expect(errors[0].errorRange).toEqual([8, 12])
expect(errors[1].errorRange).toEqual([15, 12], [28, 12])
expect(errors[1].errorRange).toEqual([15, 12])
})
test('early access file with early access references passes', async () => {
const result = await runRule(frontmatterEarlyAccessReferences, {

View File

@@ -22,8 +22,8 @@ describe(tableColumnIntegrity.names.join(' - '), () => {
const errors = result.markdown
expect(errors.length).toBe(1)
expect(errors[0].lineNumber).toBe(3)
if (errors[0].detail) {
expect(errors[0].detail).toContain('Table row has 3 columns but header has 2')
if ((errors[0] as any).detail) {
expect((errors[0] as any).detail).toContain('Table row has 3 columns but header has 2')
} else if (errors[0].errorDetail) {
expect(errors[0].errorDetail).toContain('Table row has 3 columns but header has 2')
} else {
@@ -38,8 +38,8 @@ describe(tableColumnIntegrity.names.join(' - '), () => {
const errors = result.markdown
expect(errors.length).toBe(1)
expect(errors[0].lineNumber).toBe(3)
if (errors[0].detail) {
expect(errors[0].detail).toContain('Table row has 2 columns but header has 3')
if ((errors[0] as any).detail) {
expect((errors[0] as any).detail).toContain('Table row has 2 columns but header has 3')
} else if (errors[0].errorDetail) {
expect(errors[0].errorDetail).toContain('Table row has 2 columns but header has 3')
} else {

View File

@@ -6,7 +6,8 @@ import nonEnterpriseDefaultVersion from '@/versions/lib/non-enterprise-default-v
import { DataDirectory } from '@/tests/helpers/data-directory'
describe('data tag', () => {
let dd
// Using 'any' type as DataDirectory is from data-directory.js which lacks type definitions
let dd: any
const enDirBefore = languages.en.dir
beforeAll(() => {
@@ -41,7 +42,7 @@ describe('data tag', () => {
currentLanguage: 'en',
currentPath: '/en/liquid-tags/good-data-variable',
}
const rendered = await page.render(context)
const rendered = await page!.render(context)
// The test fixture contains:
// {% data variables.stuff.foo %}
// which we control the value of here in the test.
@@ -57,7 +58,7 @@ describe('data tag', () => {
currentPath: '/en/liquid-tags/bad-data-variable',
currentLanguage: 'en',
}
await expect(page.render(context)).rejects.toThrow(
await expect(page!.render(context)).rejects.toThrow(
"Can't find the key 'foo.bar.tipu' in the scope., line:2, col:1",
)
})

View File

@@ -7,8 +7,10 @@ import { DataDirectory } from '@/tests/helpers/data-directory'
describe('liquid helper tags', () => {
vi.setConfig({ testTimeout: 60 * 1000 })
const context = {}
let dd
// Using 'any' type as context is a test fixture with dynamic properties set in beforeAll
const context: any = {}
// Using 'any' type as DataDirectory is from data-directory.js which lacks type definitions
let dd: any
const enDirBefore = languages.en.dir
beforeAll(() => {

View File

@@ -4,6 +4,7 @@ import { extname, basename } from 'path'
import walk from 'walk-sync'
import { beforeAll, describe, expect, test } from 'vitest'
import type { ValidateFunction, SchemaObject } from 'ajv'
import { getJsonValidator, validateJson } from '@/tests/lib/validate-json-schema'
import { formatAjvErrors } from '@/tests/helpers/schemas'
@@ -19,7 +20,8 @@ const yamlWalkOptions = {
}
for (const dataDir of directorySchemas) {
let schema, validate
let schema: SchemaObject
let validate: ValidateFunction
const dataDirectoryName = basename(dataDir)
const yamlFileList = walk(dataDir, yamlWalkOptions).sort()
@@ -32,7 +34,7 @@ for (const dataDir of directorySchemas) {
test.each(yamlFileList)('%p', async (yamlAbsPath) => {
const yamlContent = yaml.load(readFileSync(yamlAbsPath, 'utf8'))
const isValid = validate(yamlContent)
const formattedErrors = isValid ? validate.errors : formatAjvErrors(validate.errors)
const formattedErrors = isValid ? undefined : formatAjvErrors(validate.errors || [])
expect(isValid, formattedErrors).toBe(true)
})
})
@@ -43,6 +45,7 @@ describe('single data files', () => {
const ymlData = yaml.load(readFileSync(filepath, 'utf8'))
const schema = (await import(dataSchemas[filepath])).default
const { isValid, errors } = validateJson(schema, ymlData)
expect(isValid, errors).toBe(true)
const formattedErrors = isValid ? undefined : formatAjvErrors(errors || [])
expect(isValid, formattedErrors).toBe(true)
})
})

View File

@@ -20,7 +20,7 @@ describe('data-directory', () => {
})
test('option: preprocess function', async () => {
const preprocess = function (content) {
const preprocess = function (content: string) {
return content.replace('markdown', 'MARKDOWN')
}
const data = dataDirectory(fixturesDir, { preprocess })
@@ -35,7 +35,7 @@ describe('data-directory', () => {
})
test('option: ignorePatterns', async () => {
const ignorePatterns = []
const ignorePatterns: RegExp[] = []
// README is ignored by default
expect('README' in dataDirectory(fixturesDir)).toBe(false)

View File

@@ -1,3 +1,5 @@
import type { NextFunction } from 'express'
// Fastly provides a Soft Purge feature that allows you to mark content as outdated (stale) instead of permanently
// purging and thereby deleting it from Fastly's caches. Objects invalidated with Soft Purge will be treated as
// outdated (stale) while Fastly fetches a new version from origin.
@@ -14,7 +16,8 @@ export const SURROGATE_ENUMS = {
MANUAL: 'manual-purge',
}
export function setFastlySurrogateKey(res, enumKey, isCustomKey = false) {
// Using 'any' type for res parameter to maintain compatibility with Express Response objects
export function setFastlySurrogateKey(res: any, enumKey: string, isCustomKey = false) {
if (process.env.NODE_ENV !== 'production') {
if (!isCustomKey && !Object.values(SURROGATE_ENUMS).includes(enumKey)) {
throw new Error(
@@ -27,17 +30,21 @@ export function setFastlySurrogateKey(res, enumKey, isCustomKey = false) {
res.set(KEY, enumKey)
}
export function setDefaultFastlySurrogateKey(req, res, next) {
// Using 'any' type for req and res parameters to maintain backward compatibility with test mock objects
// that don't fully implement ExtendedRequest and Response interfaces
export function setDefaultFastlySurrogateKey(req: any, res: any, next: NextFunction) {
res.set(KEY, `${SURROGATE_ENUMS.DEFAULT} ${makeLanguageSurrogateKey()}`)
return next()
}
export function setLanguageFastlySurrogateKey(req, res, next) {
// Using 'any' type for req and res parameters to maintain backward compatibility with test mock objects
// that don't fully implement ExtendedRequest and Response interfaces
export function setLanguageFastlySurrogateKey(req: any, res: any, next: NextFunction) {
res.set(KEY, `${SURROGATE_ENUMS.DEFAULT} ${makeLanguageSurrogateKey(req.language)}`)
return next()
}
export function makeLanguageSurrogateKey(langCode) {
export function makeLanguageSurrogateKey(langCode?: string) {
if (!langCode) {
return 'no-language'
}

View File

@@ -3,6 +3,7 @@ import { describe, expect, test, vi } from 'vitest'
import { loadPageMap, loadPages } from '@/frame/lib/page-data'
import { renderContent } from '@/content-render/index'
import { allVersions } from '@/versions/lib/all-versions'
import type { Permalink } from '@/types'
describe('toc links', () => {
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
@@ -20,7 +21,8 @@ describe('toc links', () => {
for (const pageVersion of Object.keys(allVersions)) {
for (const page of englishIndexPages) {
// skip page if it doesn't have a permalink for the current product version
if (!page.permalinks.some((permalink) => permalink.pageVersion === pageVersion)) continue
if (!page.permalinks.some((permalink: Permalink) => permalink.pageVersion === pageVersion))
continue
// build fake context object for rendering the page
const context = {
@@ -38,7 +40,7 @@ describe('toc links', () => {
} catch (err) {
issues.push({
'TOC path': page.relativePath,
error: err.message,
error: err instanceof Error ? err.message : String(err),
pageVersion,
})
}

View File

@@ -10,10 +10,15 @@ import {
getPreviews,
} from '../lib/index'
interface GraphqlType {
kind: string
type: string
}
describe('graphql schema', () => {
const graphqlTypes = JSON.parse(readFileSync('src/graphql/lib/types.json')).map(
(item) => item.kind,
)
const graphqlTypes = (
JSON.parse(readFileSync('src/graphql/lib/types.json', 'utf-8')) as GraphqlType[]
).map((item) => item.kind)
for (const version in allVersions) {
for (const type of graphqlTypes) {
test(`getting the GraphQL ${type} schema works for ${version}`, async () => {

View File

@@ -2,6 +2,7 @@ import { describe, expect, test } from 'vitest'
import { getDOM } from '@/tests/helpers/e2etest'
import { loadPages } from '@/frame/lib/page-data'
import type { Permalink } from '@/types'
const pageList = await loadPages(undefined, ['en'])
@@ -27,7 +28,9 @@ describe('server rendering certain GraphQL pages', () => {
)
const nonFPTPermalinks = autogeneratedPages
.map((page) =>
page.permalinks.find((permalink) => permalink.pageVersion !== 'free-pro-team@latest'),
page.permalinks.find(
(permalink: Permalink) => permalink.pageVersion !== 'free-pro-team@latest',
),
)
.filter(Boolean)
const nonFPTPermalinksHrefs = nonFPTPermalinks.map((permalink) => {

View File

@@ -13,7 +13,7 @@ const liquidEndRex = /{%-?\s*endif\s*-?%}$/
// {% ifversion ghes%}/foo/bar{%endif %}
//
// And if no liquid, just return as is.
function stripLiquid(text) {
function stripLiquid(text: string): string {
if (liquidStartRex.test(text) && liquidEndRex.test(text)) {
return text.replace(liquidStartRex, '').replace(liquidEndRex, '').trim()
} else if (text.includes('{')) {
@@ -26,7 +26,9 @@ function stripLiquid(text) {
// return undefined if it can found as a known page.
// Otherwise, return an object with information that is used to
// print a useful test error message in the assertion.
export function checkURL(uri, index, redirectsContext) {
// Using 'any' type for redirectsContext parameter as it's a complex context object
// with dynamic structure that would require extensive type definitions
export function checkURL(uri: string, index: number, redirectsContext: any) {
const url = `/en${stripLiquid(uri).split('#')[0]}`
if (!(url in redirectsContext.pages)) {
// Some are written without a version, but don't work with the

View File

@@ -1,13 +0,0 @@
import type { AllVersions } from '@/types'
export const allVersionKeys: string[]
export const allVersionShortnames: Record<string, string>
export declare function isApiVersioned(version: string): boolean
export declare function getDocsVersion(openApiVersion: string): string
export declare function getOpenApiVersion(version: string): string
export const allVersions: AllVersions

View File

@@ -6,6 +6,7 @@ import { latest } from '@/versions/lib/enterprise-server-releases'
import schema from '@/tests/helpers/schemas/versions-schema'
import nonEnterpriseDefaultVersion from '@/versions/lib/non-enterprise-default-version'
import { formatAjvErrors } from '@/tests/helpers/schemas'
import type { Version } from '@/types'
const validate = getJsonValidator(schema)
@@ -16,12 +17,13 @@ describe('versions module', () => {
})
test('every version is valid', () => {
Object.values(allVersions).forEach((versionObj) => {
Object.values(allVersions).forEach((versionObj: Version) => {
const versionName = versionObj.version
const isValid = validate(versionObj)
let errors
let errors: string | undefined
if (!isValid) {
errors = `version '${versionObj.version}': ${formatAjvErrors(validate.errors)}`
errors = `version '${versionName}': ${formatAjvErrors(validate.errors || [])}`
}
expect(isValid, errors).toBe(true)
@@ -29,7 +31,7 @@ describe('versions module', () => {
})
test('check REST api calendar date versioned versions set to correct latestApiVersion', () => {
Object.values(allVersions).forEach((versionObj) => {
Object.values(allVersions).forEach((versionObj: Version) => {
if (versionObj.apiVersions.length > 0) {
const latestApiVersion = versionObj.latestApiVersion
const apiVersions = versionObj.apiVersions