vitest/docs/.vitepress/scripts/cli-generator.ts
2025-11-06 14:59:05 +01:00

91 lines
2.6 KiB
TypeScript

import type { CLIOption, CLIOptions } from '../../../packages/vitest/src/node/cli/cli-config'
import { writeFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { cliOptionsConfig } from '../../../packages/vitest/src/node/cli/cli-config'
const docsDir = resolve(dirname(fileURLToPath(import.meta.url)), '../..')
const cliTablePath = resolve(docsDir, './guide/cli-generated.md')
const nonNullable = <T>(value: T): value is NonNullable<T> => value !== null && value !== undefined
const skipCli = new Set([
'mergeReports',
'changed',
'shard',
])
const skipConfig = new Set([
'config',
'api.port',
'api.host',
'api.strictPort',
'coverage.watermarks.statements',
'coverage.watermarks.lines',
'coverage.watermarks.branches',
'coverage.watermarks.functions',
'coverage.thresholds.statements',
'coverage.thresholds.branches',
'coverage.thresholds.functions',
'coverage.thresholds.lines',
'standalone',
'clearScreen',
'configLoader',
'color',
'run',
'hideSkippedTests',
'dom',
'inspect',
'inspectBrk',
'project',
'ui',
'browser.name',
'browser.fileParallelism',
])
function resolveOptions(options: CLIOptions<any>, parentName?: string) {
return Object.entries(options).flatMap(
([subcommandName, subcommandConfig]) => resolveCommand(
parentName ? `${parentName}.${subcommandName}` : subcommandName,
subcommandConfig,
),
).filter(nonNullable)
}
function resolveCommand(name: string, config: CLIOption<any> | null): any {
if (!config || skipCli.has(name)) {
return null
}
let title = '`'
if (config.shorthand) {
title += `-${config.shorthand}, `
}
title += `--${config.alias || name}`
if ('argument' in config) {
title += ` ${config.argument}`
}
title += '`'
if ('subcommands' in config && config.subcommands) {
return resolveOptions(config.subcommands, name)
}
return {
title: name,
cli: title,
description: config.description,
}
}
const options = resolveOptions(cliOptionsConfig)
const template = options.map((option) => {
const title = option.title
const cli = option.cli
const [page, ...hash] = (title.startsWith('browser.') ? title.slice(8) : title).toLowerCase().split('.')
const config = skipConfig.has(title) ? '' : `[${title}](${title.includes('browser.') ? '/config/browser/' : '/config/'}${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''})`
return `### ${title}\n\n- **CLI:** ${cli}\n${config ? `- **Config:** ${config}\n` : ''}\n${option.description.replace(/https:\/\/vitest\.dev\//g, '/')}\n`
}).join('\n')
writeFileSync(cliTablePath, template, 'utf-8')