import output from '@/output' import { exportResults } from '@/scripts/scan/export-results' import { printResults } from '@/scripts/scan/print-results' import { type ScanTargetType, getScanTarget } from '@/scripts/scan/scan-target' import { traverse } from '@/scripts/scan/traverse' import { getPluginConfigContent } from '@/scripts/shared' import { getScanConfig, scanCodingAPIs, findMatchedCodingApis, scanPluginConfig, findMatchedConfigApis, } from '@ones-open/cli-utils' import type { ScanConfigSchema, ApiScanResultItem, PluginConfigScanResultItem, } from '@ones-open/cli-utils' import Listr from 'listr' interface ScanContext { scanTargets: ScanTargetType[] scanConfig: ScanConfigSchema apiScanResults: ApiScanResultItem[] // mutable pluginConfigScanResults: PluginConfigScanResultItem[] // mutable } const scan = async (rawTarget: ScanTargetType | undefined, options: { output: string }) => { const { output: outputPath } = options try { const tasks = new Listr([ { title: 'load the config', task: async (ctx) => { const scanTargets = getScanTarget(rawTarget) const scanConfig = await getScanConfig() ctx.scanTargets = scanTargets ctx.scanConfig = scanConfig ctx.apiScanResults = [] ctx.pluginConfigScanResults = [] }, }, { title: 'scan the APIs', skip: (ctx) => !ctx.scanTargets.includes('api'), task: async (ctx) => { const { roots, apis } = ctx.scanConfig const subTasks = new Listr( roots.map((rootPath) => ({ title: `scan ${rootPath}`, task: () => traverse( rootPath, async (filePath) => { ctx.apiScanResults.push( ...((await scanCodingAPIs(filePath, ctx.scanConfig)) as ApiScanResultItem[]), ) }, ctx.scanConfig, ), })), ) if (apis.length > 0) { subTasks.add([ { title: 'find matched APIs', task: () => { ctx.apiScanResults = findMatchedCodingApis(ctx.apiScanResults, ctx.scanConfig) }, }, ]) } return subTasks }, }, { title: 'scan the triggers', skip: (ctx) => !ctx.scanTargets.includes('trigger'), task: async (ctx) => { const { apis } = ctx.scanConfig const pluginConfig = await getPluginConfigContent() ctx.pluginConfigScanResults = await scanPluginConfig(pluginConfig) if (apis.length !== 0) { ctx.pluginConfigScanResults = findMatchedConfigApis( ctx.pluginConfigScanResults, ctx.scanConfig, ) } }, }, { title: 'export the result', task: async (ctx) => { await exportResults( ctx.apiScanResults, ctx.pluginConfigScanResults, ctx.scanConfig, outputPath, ) }, skip: () => { if (!outputPath) { return `no output file specified` } return false }, }, ]) const ctx = await tasks.run() printResults(ctx.apiScanResults, ctx.pluginConfigScanResults, ctx.scanConfig) } catch (error) { output.error(error) } } export { scan }